github.com/oam-dev/kubevela@v1.9.11/pkg/workflow/operation/operation_test.go (about) 1 /* 2 Copyright 2021 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package operation 18 19 import ( 20 "context" 21 22 . "github.com/onsi/ginkgo/v2" 23 . "github.com/onsi/gomega" 24 kruisev1alpha1 "github.com/openkruise/rollouts/api/v1alpha1" 25 v1 "k8s.io/api/core/v1" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/types" 28 "k8s.io/utils/pointer" 29 30 workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1" 31 32 "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 33 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 34 "github.com/oam-dev/kubevela/pkg/oam" 35 "github.com/oam-dev/kubevela/pkg/oam/util" 36 ) 37 38 var _ = Describe("Kruise rollout test", func() { 39 ctx := context.Background() 40 BeforeEach(func() { 41 Expect(k8sClient.Create(ctx, myRollout.DeepCopy())).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{})) 42 Expect(k8sClient.Create(ctx, rt.DeepCopy())).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{})) 43 Expect(k8sClient.Create(ctx, app.DeepCopy())).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{})) 44 }) 45 46 It("Suspend workflow", func() { 47 checkApp := v1beta1.Application{} 48 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 49 checkApp.Status.Workflow = &common.WorkflowStatus{ 50 Suspend: false, 51 StartTime: metav1.Now(), 52 } 53 Expect(k8sClient.Status().Update(ctx, &checkApp)).Should(BeNil()) 54 operator := NewApplicationWorkflowOperator(k8sClient, nil, checkApp.DeepCopy()) 55 checkApp = v1beta1.Application{} 56 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 57 Expect(operator.Suspend(ctx)).Should(BeNil()) 58 checkApp = v1beta1.Application{} 59 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 60 Expect(checkApp.Status.Workflow.Suspend).Should(BeEquivalentTo(true)) 61 }) 62 63 It("Resume workflow", func() { 64 checkApp := v1beta1.Application{} 65 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 66 operator := NewApplicationWorkflowOperator(k8sClient, nil, checkApp.DeepCopy()) 67 Expect(operator.Resume(ctx)).Should(BeNil()) 68 checkApp = v1beta1.Application{} 69 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 70 Expect(checkApp.Status.Workflow.Suspend).Should(BeEquivalentTo(false)) 71 }) 72 73 It("Terminate workflow", func() { 74 checkApp := v1beta1.Application{} 75 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 76 checkApp.Status.Workflow = &common.WorkflowStatus{ 77 Steps: []workflowv1alpha1.WorkflowStepStatus{ 78 { 79 StepStatus: workflowv1alpha1.StepStatus{ 80 Name: "step1", 81 Type: "suspend", 82 Phase: workflowv1alpha1.WorkflowStepPhaseSuspending, 83 }, 84 }, 85 }, 86 } 87 operator := NewApplicationWorkflowOperator(k8sClient, nil, checkApp.DeepCopy()) 88 Expect(operator.Terminate(ctx)).Should(BeNil()) 89 checkApp = v1beta1.Application{} 90 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 91 Expect(checkApp.Status.Workflow.Terminated).Should(BeEquivalentTo(true)) 92 }) 93 94 It("Restart workflow", func() { 95 checkApp := v1beta1.Application{} 96 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 97 operator := NewApplicationWorkflowOperator(k8sClient, nil, checkApp.DeepCopy()) 98 Expect(operator.Restart(ctx)).Should(BeNil()) 99 checkApp = v1beta1.Application{} 100 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 101 Expect(checkApp.Status.Workflow).Should(BeNil()) 102 }) 103 104 It("Resume workflow from step", func() { 105 checkApp := v1beta1.Application{} 106 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 107 checkApp.Status.Workflow = &common.WorkflowStatus{ 108 Steps: []workflowv1alpha1.WorkflowStepStatus{ 109 { 110 StepStatus: workflowv1alpha1.StepStatus{ 111 Name: "step1", 112 Type: "suspend", 113 Phase: workflowv1alpha1.WorkflowStepPhaseSuspending, 114 }, 115 }, 116 }, 117 } 118 Expect(k8sClient.Status().Update(ctx, &checkApp)).Should(BeNil()) 119 operator := NewApplicationWorkflowStepOperator(k8sClient, nil, checkApp.DeepCopy()) 120 Expect(operator.Resume(ctx, "step1")).Should(BeNil()) 121 checkApp = v1beta1.Application{} 122 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 123 Expect(checkApp.Status.Workflow.Suspend).Should(BeEquivalentTo(false)) 124 }) 125 126 It("Restart workflow from step", func() { 127 checkApp := v1beta1.Application{} 128 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 129 checkApp.Status.Workflow = &common.WorkflowStatus{ 130 Steps: []workflowv1alpha1.WorkflowStepStatus{ 131 { 132 StepStatus: workflowv1alpha1.StepStatus{ 133 Name: "step1", 134 Phase: workflowv1alpha1.WorkflowStepPhaseFailed, 135 }, 136 }, 137 }, 138 } 139 Expect(k8sClient.Status().Update(ctx, &checkApp)).Should(BeNil()) 140 operator := NewApplicationWorkflowStepOperator(k8sClient, nil, checkApp.DeepCopy()) 141 Expect(operator.Restart(ctx, "step1")).Should(BeNil()) 142 checkApp = v1beta1.Application{} 143 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 144 Expect(checkApp.Status.Workflow.Steps).Should(BeNil()) 145 }) 146 147 It("Rollback workflow", func() { 148 Expect(k8sClient.Create(ctx, &appRev)).Should(BeNil()) 149 checkAppRev := v1beta1.ApplicationRevision{} 150 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app-v1"}, &checkAppRev)).Should(BeNil()) 151 checkAppRev.Status.Succeeded = true 152 Expect(k8sClient.Status().Update(ctx, checkAppRev.DeepCopy())).Should(BeNil()) 153 154 checkApp := v1beta1.Application{} 155 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 156 checkApp.Status.Workflow = &common.WorkflowStatus{ 157 Finished: true, 158 } 159 Expect(k8sClient.Status().Update(ctx, &checkApp)).Should(BeNil()) 160 checkApp.Annotations = map[string]string{ 161 oam.AnnotationPublishVersion: "v2", 162 } 163 operator := NewApplicationWorkflowOperator(k8sClient, nil, checkApp.DeepCopy()) 164 Expect(operator.Rollback(ctx)).Should(BeNil()) 165 166 checkApp = v1beta1.Application{} 167 Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "opt-app"}, &checkApp)).Should(BeNil()) 168 // must rollback to v1 169 Expect(oam.GetPublishVersion(&checkApp)).Should(BeEquivalentTo("v1")) 170 Expect(checkApp.Status.LatestRevision.Name).Should(BeEquivalentTo("opt-app-v1")) 171 Expect(checkApp.Status.LatestRevision.Revision).Should(BeEquivalentTo(1)) 172 }) 173 }) 174 175 var app = v1beta1.Application{ 176 TypeMeta: metav1.TypeMeta{ 177 APIVersion: "core.oam.dev/v1beta1", 178 Kind: "Application", 179 }, 180 ObjectMeta: metav1.ObjectMeta{ 181 Name: "opt-app", 182 Namespace: "default", 183 Generation: 1, 184 Labels: map[string]string{ 185 oam.AnnotationPublishVersion: "v2", 186 }, 187 }, 188 Spec: v1beta1.ApplicationSpec{ 189 Components: []common.ApplicationComponent{}, 190 }, 191 } 192 193 var rt = v1beta1.ResourceTracker{ 194 TypeMeta: metav1.TypeMeta{ 195 APIVersion: "core.oam.dev/v1beta1", 196 Kind: "ResourceTracker", 197 }, 198 ObjectMeta: metav1.ObjectMeta{ 199 Name: "rollout-app", 200 Labels: map[string]string{ 201 "app.oam.dev/appRevision": "opt-app-v1", 202 "app.oam.dev/name": "opt-app", 203 "app.oam.dev/namespace": "default", 204 }, 205 }, 206 Spec: v1beta1.ResourceTrackerSpec{ 207 ApplicationGeneration: 1, 208 Type: v1beta1.ResourceTrackerTypeVersioned, 209 ManagedResources: []v1beta1.ManagedResource{ 210 { 211 ClusterObjectReference: common.ClusterObjectReference{ 212 ObjectReference: v1.ObjectReference{ 213 APIVersion: "rollouts.kruise.io/v1alpha1", 214 Kind: "Rollout", 215 Name: "my-rollout", 216 Namespace: "default", 217 }, 218 }, 219 OAMObjectReference: common.OAMObjectReference{ 220 Component: "my-rollout", 221 }, 222 }, 223 }, 224 }, 225 } 226 227 var appRev = v1beta1.ApplicationRevision{ 228 TypeMeta: metav1.TypeMeta{ 229 APIVersion: "core.oam.dev/v1beta1", 230 Kind: "ApplicationRevision", 231 }, 232 ObjectMeta: metav1.ObjectMeta{ 233 Name: "opt-app-v1", 234 Namespace: "default", 235 Labels: map[string]string{ 236 "app.oam.dev/name": "opt-app", 237 }, 238 Annotations: map[string]string{ 239 oam.AnnotationPublishVersion: "v1", 240 }, 241 }, 242 Spec: v1beta1.ApplicationRevisionSpec{ 243 ApplicationRevisionCompressibleFields: v1beta1.ApplicationRevisionCompressibleFields{ 244 Application: v1beta1.Application{ 245 Spec: v1beta1.ApplicationSpec{ 246 Components: []common.ApplicationComponent{}, 247 }, 248 }, 249 }, 250 }, 251 } 252 253 var myRollout = kruisev1alpha1.Rollout{ 254 TypeMeta: metav1.TypeMeta{ 255 APIVersion: "rollouts.kruise.io/v1alpha1", 256 Kind: "Rollout", 257 }, 258 ObjectMeta: metav1.ObjectMeta{ 259 Name: "my-rollout", 260 Namespace: "default", 261 }, 262 Spec: kruisev1alpha1.RolloutSpec{ 263 ObjectRef: kruisev1alpha1.ObjectRef{ 264 WorkloadRef: &kruisev1alpha1.WorkloadRef{ 265 APIVersion: "appsv1", 266 Kind: "Deployment", 267 Name: "canary-demo", 268 }, 269 }, 270 Strategy: kruisev1alpha1.RolloutStrategy{ 271 Canary: &kruisev1alpha1.CanaryStrategy{ 272 Steps: []kruisev1alpha1.CanaryStep{ 273 { 274 Weight: pointer.Int32(30), 275 }, 276 }, 277 }, 278 Paused: false, 279 }, 280 }, 281 }