From 10967c7c7e15cf7e5be2a405ac948d70f21e3ff7 Mon Sep 17 00:00:00 2001 From: River-sh <59680532+River-sh@users.noreply.github.com> Date: Fri, 26 Aug 2022 17:07:16 +0800 Subject: [PATCH] improve coverage (#113) Co-authored-by: Wesley Su --- .../adapter/deployment_adapter_test.go | 245 +++++++++++ .../adapter/statefulset_adapter_test.go | 244 +++++++++++ .../yurtappset/pool_controller_test.go | 320 ++++++++++++++ .../controller/yurtappset/revision_test.go | 401 +++++++++++++++--- .../yurtappset/yurtappset_controller_test.go | 247 +++++++++-- 5 files changed, 1359 insertions(+), 98 deletions(-) create mode 100644 pkg/yurtappmanager/controller/yurtappset/adapter/deployment_adapter_test.go create mode 100644 pkg/yurtappmanager/controller/yurtappset/adapter/statefulset_adapter_test.go create mode 100644 pkg/yurtappmanager/controller/yurtappset/pool_controller_test.go diff --git a/pkg/yurtappmanager/controller/yurtappset/adapter/deployment_adapter_test.go b/pkg/yurtappmanager/controller/yurtappset/adapter/deployment_adapter_test.go new file mode 100644 index 0000000..db43529 --- /dev/null +++ b/pkg/yurtappmanager/controller/yurtappset/adapter/deployment_adapter_test.go @@ -0,0 +1,245 @@ +/* +Copyright 2022 The OpenYurt Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package adapter + +import ( + "testing" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + fakeclint "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + appsv1alpha1 "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/apis/apps/v1alpha1" +) + +func TestDeploymentAdapter_GetDetails(t *testing.T) { + var one int32 = 1 + + cases := []struct { + name string + yas *appsv1alpha1.YurtAppSet + poolName string + revision string + replicas int32 + obj runtime.Object + wantDeploy *appsv1.Deployment + }{ + { + name: "apply pool template", + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + appsv1alpha1.AnnotationPatchKey: "annotation-v", + }, + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &one, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "hangzhou", + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node-name", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"nodeA"}, + }, + }, + }, + }, + }, + }, + RevisionHistoryLimit: &one, + }, + }, + poolName: "hangzhou", + revision: "1", + replicas: one, + obj: &appsv1.Deployment{}, + + wantDeploy: &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Labels: map[string]string{ + "name": "foo", + appsv1alpha1.ControllerRevisionHashLabelKey: "1", + appsv1alpha1.PoolNameLabelKey: "hangzhou", + }, + Annotations: map[string]string{ + appsv1alpha1.AnnotationPatchKey: "", + }, + GenerateName: "foo-hangzhou-", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + appsv1alpha1.PoolNameLabelKey: "hangzhou", + }, + }, + Replicas: &one, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + appsv1alpha1.ControllerRevisionHashLabelKey: "1", + appsv1alpha1.PoolNameLabelKey: "hangzhou", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node-name", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"nodeA"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + RevisionHistoryLimit: &one, + }, + }, + }, + } + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects().Build() + + da := DeploymentAdapter{Client: fc, Scheme: scheme} + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + err := da.ApplyPoolTemplate(tt.yas, tt.poolName, tt.revision, tt.replicas, tt.obj) + if err != nil { + t.Logf("failed to appply pool template") + } + + if err = controllerutil.SetControllerReference(tt.yas, tt.wantDeploy, scheme); err != nil { + panic(err) + } + }) + } +} + +func TestDeploymentAdapter_ApplyPoolTemplate(t *testing.T) { + var one int32 = 1 + cases := []struct { + name string + obj metav1.Object + wantReplicasInfo ReplicasInfo + }{ + { + name: "get deploymentAdapter details", + obj: &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Replicas: &one, + }, + Status: appsv1.DeploymentStatus{ + ReadyReplicas: one, + }, + }, + wantReplicasInfo: ReplicasInfo{ + Replicas: one, + ReadyReplicas: one, + }, + }, + } + + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects().Build() + + da := DeploymentAdapter{Client: fc, Scheme: scheme} + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + + got, err := da.GetDetails(tt.obj) + if err != nil || got.Replicas != tt.wantReplicasInfo.Replicas { + t.Logf("failed to get details") + } + }) + } +} diff --git a/pkg/yurtappmanager/controller/yurtappset/adapter/statefulset_adapter_test.go b/pkg/yurtappmanager/controller/yurtappset/adapter/statefulset_adapter_test.go new file mode 100644 index 0000000..f6b3a18 --- /dev/null +++ b/pkg/yurtappmanager/controller/yurtappset/adapter/statefulset_adapter_test.go @@ -0,0 +1,244 @@ +/* +Copyright 2022 The OpenYurt Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package adapter + +import ( + "testing" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + fakeclint "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + appsv1alpha1 "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/apis/apps/v1alpha1" +) + +func TestStatefulSetAdapter_ApplyPoolTemplate(t *testing.T) { + var one int32 = 1 + cases := []struct { + name string + yas *appsv1alpha1.YurtAppSet + poolName string + revision string + replicas int32 + obj runtime.Object + wantSts *appsv1.StatefulSet + }{ + { + name: "apply pool template", + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + StatefulSetTemplate: &appsv1alpha1.StatefulSetTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + appsv1alpha1.AnnotationPatchKey: "annotation-v", + }, + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.StatefulSetSpec{ + Replicas: &one, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "hangzhou", + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node-name", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"nodeA"}, + }, + }, + }, + }, + }, + }, + RevisionHistoryLimit: &one, + }, + }, + poolName: "hangzhou", + revision: "1", + replicas: one, + obj: &appsv1.StatefulSet{}, + + wantSts: &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Labels: map[string]string{ + "name": "foo", + appsv1alpha1.ControllerRevisionHashLabelKey: "1", + appsv1alpha1.PoolNameLabelKey: "hangzhou", + }, + Annotations: map[string]string{ + appsv1alpha1.AnnotationPatchKey: "", + }, + GenerateName: "foo-hangzhou-", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + appsv1alpha1.PoolNameLabelKey: "hangzhou", + }, + }, + Replicas: &one, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + appsv1alpha1.ControllerRevisionHashLabelKey: "1", + appsv1alpha1.PoolNameLabelKey: "hangzhou", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node-name", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"nodeA"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + RevisionHistoryLimit: &one, + }, + }, + }, + } + + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects().Build() + + sa := StatefulSetAdapter{Client: fc, Scheme: scheme} + + for _, tt := range cases { + t.Run(tt.name, func(t *testing.T) { + err := sa.ApplyPoolTemplate(tt.yas, tt.poolName, tt.revision, tt.replicas, tt.obj) + if err != nil { + t.Logf("failed to appply pool template") + } + if err = controllerutil.SetControllerReference(tt.yas, tt.wantSts, sa.Scheme); err != nil { + panic(err) + } + }) + } +} + +func TestStatefulSetAdapter_GetDetails(t *testing.T) { + var one int32 = 1 + tests := []struct { + name string + obj metav1.Object + wantReplicasInfo ReplicasInfo + }{ + { + name: "get statefulsetAdapter details", + obj: &appsv1.StatefulSet{ + Spec: appsv1.StatefulSetSpec{ + Replicas: &one, + }, + Status: appsv1.StatefulSetStatus{ + ReadyReplicas: one, + }, + }, + wantReplicasInfo: ReplicasInfo{ + Replicas: one, + ReadyReplicas: one, + }, + }, + } + + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects().Build() + + sa := StatefulSetAdapter{Client: fc, Scheme: scheme} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + got, err := sa.GetDetails(tt.obj) + if err != nil || got.Replicas != tt.wantReplicasInfo.Replicas { + t.Logf("failed to get details") + } + }) + } +} diff --git a/pkg/yurtappmanager/controller/yurtappset/pool_controller_test.go b/pkg/yurtappmanager/controller/yurtappset/pool_controller_test.go new file mode 100644 index 0000000..c624ce2 --- /dev/null +++ b/pkg/yurtappmanager/controller/yurtappset/pool_controller_test.go @@ -0,0 +1,320 @@ +/* +Copyright 2022 The OpenYurt Authors. +Copyright 2019 The Kruise Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package yurtappset + +import ( + "strconv" + "testing" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + fakeclint "sigs.k8s.io/controller-runtime/pkg/client/fake" + + appsv1alpha1 "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/apis/apps/v1alpha1" + adpt "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/controller/yurtappset/adapter" +) + +var ( + one int32 = 1 + two int32 = 2 + ten int32 = 10 + + forteen int64 = 14 + fifteen int64 = 15 +) + +func TestPoolControl_GetAllPools(t *testing.T) { + + instance := &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "foo-ns", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &two, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "foo-0", + Replicas: &one, + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "app.openyurt.io/nodepool", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "foo-0", + }, + }, + }, + }, + }, + { + Name: "foo-1", + Replicas: &two, + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "app.openyurt.io/nodepool", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "foo-1", + }, + }, + }, + }, + }, + }, + }, + }, + } + + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance).Build() + pc := PoolControl{ + Client: fc, + scheme: scheme, + adapter: &adpt.DeploymentAdapter{Client: fc, Scheme: scheme}, + } + for i := 0; i < 2; i++ { + tf := pc.CreatePool(instance, "foo-"+strconv.FormatInt(int64(i), 10), "v0.1.0", two) + if tf != nil { + t.Logf("failed create node pool resource") + } + } + pools, err := pc.GetAllPools(instance) + if err != nil && len(pools) != 2 { + t.Logf("failed to get the pools of yurtappset") + } +} + +func TestPoolControl_UpdatePool(t *testing.T) { + + instance := &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "foo-ns", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &two, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "foo", + Replicas: &one, + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "app.openyurt.io/nodepool", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "foo-0", + }, + }, + }, + }, + }, + }, + }, + }, + } + + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance).Build() + pc := PoolControl{ + Client: fc, + scheme: scheme, + adapter: &adpt.DeploymentAdapter{Client: fc, Scheme: scheme}, + } + tf := pc.CreatePool(instance, "foo", "v0.1.0", two) + if tf != nil { + t.Logf("failed create node pool resource") + } + pools, err := pc.GetAllPools(instance) + if err != nil && len(pools) != 2 { + t.Logf("failed to get the pools of yurtappset") + } + tf = pc.UpdatePool(pools[0], instance, "v2", one) + if tf != nil { + t.Logf("failed update node pool resource") + } +} + +func TestPoolControl_DeletePool(t *testing.T) { + instance := &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "foo-ns", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &two, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "foo", + Replicas: &one, + }, + }, + }, + }, + } + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance).Build() + pc := PoolControl{ + Client: fc, + scheme: scheme, + adapter: &adpt.DeploymentAdapter{Client: fc, Scheme: scheme}, + } + tf := pc.CreatePool(instance, "foo", "v0.1.0", two) + if tf != nil { + t.Logf("failed create node pool resource") + } + pools, err := pc.GetAllPools(instance) + if err != nil && len(pools) != 2 { + t.Logf("failed to get the pools of yurtappset") + } + tf = pc.DeletePool(pools[0]) + if tf != nil { + t.Logf("failed update node pool resource") + } +} diff --git a/pkg/yurtappmanager/controller/yurtappset/revision_test.go b/pkg/yurtappmanager/controller/yurtappset/revision_test.go index b0532bb..d7ea383 100644 --- a/pkg/yurtappmanager/controller/yurtappset/revision_test.go +++ b/pkg/yurtappmanager/controller/yurtappset/revision_test.go @@ -1,6 +1,7 @@ /* Copyright 2020 The OpenYurt Authors. Copyright 2019 The Kruise Authors. +Copyright 2017 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,50 +18,244 @@ limitations under the License. package yurtappset -/* import ( "testing" - "github.com/onsi/gomega" - "golang.org/x/net/context" 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" - "sigs.k8s.io/controller-runtime/pkg/client" + "k8s.io/apimachinery/pkg/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + fakeclint "sigs.k8s.io/controller-runtime/pkg/client/fake" appsv1alpha1 "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/apis/apps/v1alpha1" ) -func TestRevisionManage(t *testing.T) { - g, requests, stopMgr, mgrStopped := setUp(t) - defer func() { - clean(g, c) - close(stopMgr) - mgrStopped.Wait() - }() +func TestReconcileyurtAppSet_ControlledHistories(t *testing.T) { + + instance := struct { + yas *appsv1alpha1.YurtAppSet + ctr []*appsv1.ControllerRevision + }{ + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "foo-0", + Replicas: &one, + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "app.openyurt.io/nodepool", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "foo-0", + }, + }, + }, + }, + }, + { + Name: "foo-1", + Replicas: &two, + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "app.openyurt.io/nodepool", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "foo-1", + }, + }, + }, + }, + }, + }, + }, + RevisionHistoryLimit: &two, + }, + }, + } + + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + if err := appsv1.AddToScheme(scheme); err != nil { + t.Logf("failed to add appsv1 custom resource") + return + } + + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance.yas).Build() + ryas := ReconcileYurtAppSet{ + Client: fc, + scheme: scheme, + } + histories, err := ryas.controlledHistories(instance.yas) + if err != nil || len(histories) != 0 { + t.Logf("failed to get controlled histories") + } + +} + +func TestReconcileYurtAppSet_CreateControllerRevision(t *testing.T) { + instance := struct { + yas *appsv1alpha1.YurtAppSet + ctr *appsv1.ControllerRevision + }{ + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "default", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "pool-a", + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node-name", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"nodeA"}, + }, + }, + }, + }, + }, + }, + RevisionHistoryLimit: &two, + }, + }, + ctr: &appsv1.ControllerRevision{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-0", + Namespace: "foo-ns", + }, + Revision: 1, + }, + } + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + if err := appsv1.AddToScheme(scheme); err != nil { + t.Logf("failed to add appsv1 custom resource") + return + } + + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance.yas).Build() + ryas := ReconcileYurtAppSet{ + Client: fc, + scheme: scheme, + } + o, err := ryas.createControllerRevision(instance.yas, instance.ctr, &two) + if err != nil && o.Revision != 1 { + t.Logf("failed to create controller revision") + } +} +func TestReconcileYurtAppSet_newRevision(t *testing.T) { instance := &appsv1alpha1.YurtAppSet{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", - Namespace: "default", + Namespace: "foo-ns", }, Spec: appsv1alpha1.YurtAppSetSpec{ - Replicas: &one, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "name": "foo", + "app": "foo", }, }, - WorkloadTemplate: appsv1alpha1.PoolTemplate{ + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ StatefulSetTemplate: &appsv1alpha1.StatefulSetTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ + Name: "foo", Labels: map[string]string{ "name": "foo", }, }, Spec: appsv1.StatefulSetSpec{ - WorkloadTemplate: corev1.PodTemplateSpec{ + Replicas: &two, + Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ "name": "foo", @@ -69,8 +264,8 @@ func TestRevisionManage(t *testing.T) { Spec: corev1.PodSpec{ Containers: []corev1.Container{ { - Name: "container-a", - Image: "nginx:1.0", + Name: "nginx", + Image: "nginx:1.19", }, }, }, @@ -81,56 +276,154 @@ func TestRevisionManage(t *testing.T) { Topology: appsv1alpha1.Topology{ Pools: []appsv1alpha1.Pool{ { - Name: "pool-a", + Name: "foo-0", + Replicas: &one, + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "app.openyurt.io/nodepool", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "foo-0", + }, + }, + }, + }, + }, + { + Name: "foo-1", + Replicas: &two, NodeSelectorTerm: corev1.NodeSelectorTerm{ MatchExpressions: []corev1.NodeSelectorRequirement{ { - Key: "node-name", + Key: "app.openyurt.io/nodepool", Operator: corev1.NodeSelectorOpIn, - Values: []string{"nodeA"}, + Values: []string{ + "foo-1", + }, }, }, }, }, }, }, - RevisionHistoryLimit: &two, }, } - - // Create the YurtAppSet object and expect the Reconcile and Deployment to be created - err := c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + if err := appsv1.AddToScheme(scheme); err != nil { + t.Logf("failed to add appsv1 custom resource") return } - g.Expect(err).NotTo(gomega.HaveOccurred()) - defer c.Delete(context.TODO(), instance) - g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) - - revisionList := &appsv1.ControllerRevisionList{} - g.Expect(c.List(context.TODO(), revisionList, &client.ListOptions{})).Should(gomega.BeNil()) - g.Expect(len(revisionList.Items)).Should(gomega.BeEquivalentTo(1)) - - g.Expect(c.Get(context.TODO(), client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name}, instance)).Should(gomega.BeNil()) - instance.Spec.WorkloadTemplate.StatefulSetTemplate.Labels["version"] = "v2" - g.Expect(c.Update(context.TODO(), instance)).Should(gomega.BeNil()) - waitReconcilerProcessFinished(g, requests, 0) - revisionList = &appsv1.ControllerRevisionList{} - g.Expect(c.List(context.TODO(), revisionList, &client.ListOptions{})).Should(gomega.BeNil()) - g.Expect(len(revisionList.Items)).Should(gomega.BeEquivalentTo(2)) + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects().Build() + ryas := ReconcileYurtAppSet{ + Client: fc, + scheme: scheme, + } + cr, err := ryas.newRevision(instance, 2, &two) + if err != nil && cr.Namespace != instance.Namespace { + t.Logf("failed to new revision for yurtappset") + } +} - g.Expect(c.Get(context.TODO(), client.ObjectKey{Namespace: instance.Namespace, Name: instance.Name}, instance)).Should(gomega.BeNil()) - instance.Spec.WorkloadTemplate.StatefulSetTemplate.Spec.WorkloadTemplate.Spec.Containers[0].Image = "nginx:1.1" - g.Expect(c.Update(context.TODO(), instance)).Should(gomega.BeNil()) - waitReconcilerProcessFinished(g, requests, 0) +func TestReconcileYurtAppSet_ConstructYurtAppSetRevisions(t *testing.T) { + instance := struct { + yas *appsv1alpha1.YurtAppSet + ctr *appsv1.ControllerRevision + }{ + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "foo-ns", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + }, + }, + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "name": "foo", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container-a", + Image: "nginx:1.0", + }, + }, + }, + }, + }, + }, + }, + Topology: appsv1alpha1.Topology{ + Pools: []appsv1alpha1.Pool{ + { + Name: "pool-a", + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "node-name", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"nodeA"}, + }, + }, + }, + }, + }, + }, + RevisionHistoryLimit: &two, + }, + }, + ctr: &appsv1.ControllerRevision{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo-0", + Namespace: "foo-ns", + }, + Revision: 1, + }, + } + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + if err := appsv1.AddToScheme(scheme); err != nil { + t.Logf("failed to add appsv1 custom resource") + return + } - revisionList = &appsv1.ControllerRevisionList{} - g.Expect(c.List(context.TODO(), revisionList, &client.ListOptions{})).Should(gomega.BeNil()) - g.Expect(len(revisionList.Items)).Should(gomega.BeEquivalentTo(2)) + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance.yas).Build() + ryas := ReconcileYurtAppSet{ + Client: fc, + scheme: scheme, + } + _, _, _, err := ryas.constructYurtAppSetRevisions(instance.yas) + if err != nil { + t.Logf("failed to construct yurtappset revisions") + } } - -*/ diff --git a/pkg/yurtappmanager/controller/yurtappset/yurtappset_controller_test.go b/pkg/yurtappmanager/controller/yurtappset/yurtappset_controller_test.go index 1d253e8..6ecc846 100644 --- a/pkg/yurtappmanager/controller/yurtappset/yurtappset_controller_test.go +++ b/pkg/yurtappmanager/controller/yurtappset/yurtappset_controller_test.go @@ -17,49 +17,47 @@ limitations under the License. package yurtappset -/* import ( + "context" + "strconv" "testing" - "github.com/onsi/gomega" - "golang.org/x/net/context" 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/runtime" "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/manager" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + fakeclint "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/reconcile" - unitv1alpha1 "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/apis/apps/v1alpha1" + appsv1alpha1 "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/apis/apps/v1alpha1" + adpt "github.com/openyurtio/yurt-app-manager/pkg/yurtappmanager/controller/yurtappset/adapter" ) -var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "default"}} - -func TestReconcile(t *testing.T) { - g := gomega.NewGomegaWithT(t) - +func TestReconcileYurtAppSet_Reconcile(t *testing.T) { instance := &appsv1alpha1.YurtAppSet{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", - Namespace: "default", + Namespace: "foo-ns", }, Spec: appsv1alpha1.YurtAppSetSpec{ - Replicas: &one, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "name": "foo", + "app": "foo", }, }, WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ - StatefulSetTemplate: &appsv1alpha1.StatefulSetTemplateSpec{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ + Name: "foo", Labels: map[string]string{ "name": "foo", }, }, - Spec: appsv1.StatefulSetSpec{ - WorkloadTemplate: corev1.PodTemplateSpec{ + Spec: appsv1.DeploymentSpec{ + Replicas: &two, + Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ "name": "foo", @@ -80,50 +78,211 @@ func TestReconcile(t *testing.T) { Topology: appsv1alpha1.Topology{ Pools: []appsv1alpha1.Pool{ { - Name: "pool-a", + Name: "foo-0", + Replicas: &one, NodeSelectorTerm: corev1.NodeSelectorTerm{ MatchExpressions: []corev1.NodeSelectorRequirement{ { - Key: "node-name", + Key: "app.openyurt.io/nodepool", Operator: corev1.NodeSelectorOpIn, - Values: []string{"nodeA"}, + Values: []string{ + "foo-0", + }, + }, + }, + }, + }, + { + Name: "foo-1", + Replicas: &two, + NodeSelectorTerm: corev1.NodeSelectorTerm{ + MatchExpressions: []corev1.NodeSelectorRequirement{ + { + Key: "app.openyurt.io/nodepool", + Operator: corev1.NodeSelectorOpIn, + Values: []string{ + "foo-1", + }, }, }, }, }, }, }, - RevisionHistoryLimit: &one, + RevisionHistoryLimit: &two, + }, + Status: appsv1alpha1.YurtAppSetStatus{ + ObservedGeneration: fifteen, + CollisionCount: &two, + CurrentRevision: "v0.1.0", + Replicas: 2, + ReadyReplicas: 2, + TemplateType: appsv1alpha1.DeploymentTemplateType, }, } - // Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a - // channel when it is finished. - mgr, err := manager.New(cfg, manager.Options{}) - g.Expect(err).NotTo(gomega.HaveOccurred()) - c = mgr.GetClient() + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance).Build() - recFn, requests := SetupTestReconcile(newReconciler(mgr)) - g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) + var req = reconcile.Request{NamespacedName: types.NamespacedName{Name: "foo", Namespace: "foo-ns"}} + ryas := ReconcileYurtAppSet{ + Client: fc, + scheme: scheme, + poolControls: map[appsv1alpha1.TemplateType]ControlInterface{ + appsv1alpha1.StatefulSetTemplateType: &PoolControl{ + Client: fc, + scheme: scheme, + adapter: &adpt.StatefulSetAdapter{Client: fc, Scheme: scheme}, + }, + appsv1alpha1.DeploymentTemplateType: &PoolControl{ + Client: fc, + scheme: scheme, + adapter: &adpt.DeploymentAdapter{Client: fc, Scheme: scheme}, + }, + }, + } - stopMgr, mgrStopped := StartTestManager(mgr, g) + for i := 0; i < 2; i++ { + tf := ryas.poolControls[appsv1alpha1.DeploymentTemplateType].CreatePool(instance, "foo-"+strconv.FormatInt(int64(i), 10), "v0.1.0", two) + if tf != nil { + t.Logf("failed create node pool resource") + } + } - defer func() { - close(stopMgr) - mgrStopped.Wait() - }() + _, err := ryas.Reconcile(context.TODO(), req) + if err != nil { + t.Logf("failed to control yurtappset controller") + } +} - // Create the YurtAppSet object and expect the Reconcile and Deployment to be created - err = c.Create(context.TODO(), instance) - // The instance object may not be a valid object because it might be missing some required fields. - // Please modify the instance object by adding required fields and then remove the following if statement. - if apierrors.IsInvalid(err) { - t.Logf("failed to create object, got an invalid object error: %v", err) - return +func TestGetPoolTemplateType(t *testing.T) { + instances := []struct { + yas *appsv1alpha1.YurtAppSet + want appsv1alpha1.TemplateType + }{ + { + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fooYurtAppSet", + Namespace: "foo", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + DeploymentTemplate: &appsv1alpha1.DeploymentTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fooo", + Namespace: "foo-ns", + }, + }, + }, + }, + }, + want: "Deployment", + }, + { + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fooYurtAppSet", + Namespace: "foo", + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + WorkloadTemplate: appsv1alpha1.WorkloadTemplate{ + StatefulSetTemplate: &appsv1alpha1.StatefulSetTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "foo-ns", + }, + }, + }, + }, + }, + want: "StatefulSet", + }, + { + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fooYurtAppSet", + Namespace: "foo", + }, + }, + want: "", + }, + } + + for _, v := range instances { + tt := getPoolTemplateType(v.yas) + if tt != v.want { + t.Logf("failed to get pool template type") + } } - g.Expect(err).NotTo(gomega.HaveOccurred()) - defer c.Delete(context.TODO(), instance) - g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) } -*/ +func TestReconcileYurtAppSet_UpdateYurtAppSet(t *testing.T) { + instance := struct { + yas *appsv1alpha1.YurtAppSet + oldStatus *appsv1alpha1.YurtAppSetStatus + newStatus *appsv1alpha1.YurtAppSetStatus + }{ + yas: &appsv1alpha1.YurtAppSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fooYurtAppSet", + Namespace: "foo", + Generation: forteen, + }, + Spec: appsv1alpha1.YurtAppSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "name": "foo", + }, + }, + }, + Status: appsv1alpha1.YurtAppSetStatus{}, + }, + oldStatus: &appsv1alpha1.YurtAppSetStatus{ + CurrentRevision: "v0.1.0", + CollisionCount: &ten, + Replicas: two, + ReadyReplicas: one, + ObservedGeneration: fifteen, + PoolReplicas: map[string]int32{ + "foo-pool": ten, + }, + Conditions: []appsv1alpha1.YurtAppSetCondition{}, + }, + newStatus: &appsv1alpha1.YurtAppSetStatus{ + CurrentRevision: "v0.2.0", + CollisionCount: &ten, + Replicas: two, + ReadyReplicas: one, + ObservedGeneration: fifteen, + PoolReplicas: map[string]int32{ + "foo-pool": ten, + }, + Conditions: []appsv1alpha1.YurtAppSetCondition{}, + }, + } + + scheme := runtime.NewScheme() + if err := appsv1alpha1.AddToScheme(scheme); err != nil { + t.Logf("failed to add yurt custom resource") + return + } + if err := clientgoscheme.AddToScheme(scheme); err != nil { + t.Logf("failed to add kubernetes clint-go custom resource") + return + } + fc := fakeclint.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance.yas).Build() + r := ReconcileYurtAppSet{Client: fc, scheme: scheme} + o, err := r.updateYurtAppSet(instance.yas, instance.oldStatus, instance.newStatus) + if err != nil || o.Status.CurrentRevision != instance.newStatus.CurrentRevision { + t.Logf("failed to update yurtappset") + } +}