github.com/kubevela/workflow@v0.6.0/controllers/backup_test.go (about) 1 /* 2 Copyright 2022 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 controllers 18 19 import ( 20 "context" 21 "fmt" 22 "time" 23 24 . "github.com/onsi/ginkgo" 25 . "github.com/onsi/gomega" 26 appsv1 "k8s.io/api/apps/v1" 27 corev1 "k8s.io/api/core/v1" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 "sigs.k8s.io/controller-runtime/pkg/client" 30 "sigs.k8s.io/controller-runtime/pkg/reconcile" 31 32 "github.com/kubevela/workflow/api/v1alpha1" 33 "github.com/kubevela/workflow/pkg/utils" 34 ) 35 36 var _ = Describe("Test Backup", func() { 37 ctx := context.Background() 38 namespace := "test-ns" 39 40 wrTemplate := &v1alpha1.WorkflowRun{ 41 TypeMeta: metav1.TypeMeta{ 42 Kind: "WorkflowRun", 43 APIVersion: "core.oam.dev/v1alpha1", 44 }, 45 ObjectMeta: metav1.ObjectMeta{ 46 Name: "wr", 47 Namespace: namespace, 48 }, 49 Spec: v1alpha1.WorkflowRunSpec{ 50 WorkflowSpec: &v1alpha1.WorkflowSpec{ 51 Steps: []v1alpha1.WorkflowStep{ 52 { 53 WorkflowStepBase: v1alpha1.WorkflowStepBase{ 54 Name: "step-1", 55 Type: "suspend", 56 }, 57 }, 58 }, 59 }, 60 }, 61 } 62 testDefinitions := []string{"test-apply", "apply-object", "failed-render"} 63 64 BeforeEach(func() { 65 setupNamespace(ctx, namespace) 66 setupTestDefinitions(ctx, testDefinitions, namespace) 67 By("[TEST] Set up definitions before integration test") 68 }) 69 70 AfterEach(func() { 71 Expect(k8sClient.DeleteAllOf(ctx, &v1alpha1.WorkflowRun{}, client.InNamespace(namespace))).Should(Succeed()) 72 Expect(k8sClient.DeleteAllOf(ctx, &appsv1.Deployment{}, client.InNamespace(namespace))).Should(Succeed()) 73 Expect(k8sClient.DeleteAllOf(ctx, &corev1.ConfigMap{}, client.InNamespace(namespace))).Should(Succeed()) 74 }) 75 76 It("workflow not finished with finished strategy", func() { 77 backupReconciler := &BackupReconciler{ 78 Client: k8sClient, 79 Scheme: testScheme, 80 BackupArgs: BackupArgs{ 81 BackupStrategy: StrategyBackupFinishedRecord, 82 CleanOnBackup: true, 83 }, 84 } 85 wr := wrTemplate.DeepCopy() 86 wr.Name = "not-finished" 87 Expect(k8sClient.Create(ctx, wr)).Should(BeNil()) 88 89 tryReconcileBackup(backupReconciler, wr.Name, wr.Namespace) 90 wrObj := &v1alpha1.WorkflowRun{} 91 Expect(k8sClient.Get(ctx, client.ObjectKey{ 92 Name: wr.Name, 93 Namespace: wr.Namespace, 94 }, wrObj)).Should(BeNil()) 95 }) 96 97 It("workflow finished with finished strategy", func() { 98 backupReconciler := &BackupReconciler{ 99 Client: k8sClient, 100 Scheme: testScheme, 101 BackupArgs: BackupArgs{ 102 BackupStrategy: StrategyBackupFinishedRecord, 103 CleanOnBackup: true, 104 }, 105 } 106 wr := wrTemplate.DeepCopy() 107 wr.Name = "finished" 108 Expect(k8sClient.Create(ctx, wr)).Should(BeNil()) 109 wr.Status.Finished = true 110 Expect(k8sClient.Status().Update(ctx, wr)).Should(BeNil()) 111 112 tryReconcileBackup(backupReconciler, wr.Name, wr.Namespace) 113 wrObj := &v1alpha1.WorkflowRun{} 114 Expect(k8sClient.Get(ctx, client.ObjectKey{ 115 Name: wr.Name, 116 Namespace: wr.Namespace, 117 }, wrObj)).Should(utils.NotFoundMatcher{}) 118 }) 119 120 It("no strategy specified", func() { 121 backupReconciler := &BackupReconciler{ 122 Client: k8sClient, 123 Scheme: testScheme, 124 } 125 wr := wrTemplate.DeepCopy() 126 wr.Name = "no-strategy" 127 Expect(k8sClient.Create(ctx, wr)).Should(BeNil()) 128 wr.Status.Finished = true 129 Expect(k8sClient.Status().Update(ctx, wr)).Should(BeNil()) 130 131 err := reconcileBackupWithReturn(backupReconciler, wr.Name, wr.Namespace) 132 Expect(err).ShouldNot(BeNil()) 133 }) 134 135 It("workflow latest failed with failed strategy", func() { 136 backupReconciler := &BackupReconciler{ 137 Client: k8sClient, 138 Scheme: testScheme, 139 BackupArgs: BackupArgs{ 140 BackupStrategy: StrategyBackupFinishedRecord, 141 IgnoreStrategy: StrategyIgnoreLatestFailed, 142 CleanOnBackup: true, 143 }, 144 } 145 wr := wrTemplate.DeepCopy() 146 wr.Name = "latest-failed" 147 Expect(k8sClient.Create(ctx, wr)).Should(BeNil()) 148 wr.Status.Finished = true 149 wr.Status.Phase = v1alpha1.WorkflowStateFailed 150 Expect(k8sClient.Status().Update(ctx, wr)).Should(BeNil()) 151 152 tryReconcileBackup(backupReconciler, wr.Name, wr.Namespace) 153 wrObj := &v1alpha1.WorkflowRun{} 154 Expect(k8sClient.Get(ctx, client.ObjectKey{ 155 Name: wr.Name, 156 Namespace: wr.Namespace, 157 }, wrObj)).Should(BeNil()) 158 }) 159 160 It("workflow latest failed with failed strategy", func() { 161 backupReconciler := &BackupReconciler{ 162 Client: k8sClient, 163 Scheme: testScheme, 164 BackupArgs: BackupArgs{ 165 BackupStrategy: StrategyBackupFinishedRecord, 166 IgnoreStrategy: StrategyIgnoreLatestFailed, 167 CleanOnBackup: true, 168 }, 169 } 170 wr := wrTemplate.DeepCopy() 171 wr.Name = "failed-wr" 172 Expect(k8sClient.Create(ctx, wr)).Should(BeNil()) 173 wr.Status.Finished = true 174 wr.Status.Phase = v1alpha1.WorkflowStateFailed 175 wr.Status.EndTime = metav1.Now() 176 Expect(k8sClient.Status().Update(ctx, wr)).Should(BeNil()) 177 178 wr2 := wrTemplate.DeepCopy() 179 wr2.Name = "failed-wr2" 180 Expect(k8sClient.Create(ctx, wr2)).Should(BeNil()) 181 wr2.Status.Finished = true 182 wr2.Status.Phase = v1alpha1.WorkflowStateFailed 183 Expect(k8sClient.Status().Update(ctx, wr2)).Should(BeNil()) 184 185 latest := wrTemplate.DeepCopy() 186 latest.Name = "latest-failed" 187 Expect(k8sClient.Create(ctx, latest)).Should(BeNil()) 188 latest.Status.Finished = true 189 latest.Status.Phase = v1alpha1.WorkflowStateFailed 190 latest.Status.EndTime.Time = wr.Status.EndTime.Add(time.Hour) 191 Expect(k8sClient.Status().Update(ctx, latest)).Should(BeNil()) 192 193 tryReconcileBackup(backupReconciler, wr.Name, wr.Namespace) 194 wrObj := &v1alpha1.WorkflowRun{} 195 Expect(k8sClient.Get(ctx, client.ObjectKey{ 196 Name: wr.Name, 197 Namespace: wr.Namespace, 198 }, wrObj)).Should(utils.NotFoundMatcher{}) 199 200 Expect(k8sClient.Get(ctx, client.ObjectKey{ 201 Name: wr2.Name, 202 Namespace: wr2.Namespace, 203 }, wrObj)).Should(utils.NotFoundMatcher{}) 204 205 tryReconcileBackup(backupReconciler, wr2.Name, wr2.Namespace) 206 207 tryReconcileBackup(backupReconciler, latest.Name, latest.Namespace) 208 Expect(k8sClient.Get(ctx, client.ObjectKey{ 209 Name: latest.Name, 210 Namespace: latest.Namespace, 211 }, wrObj)).Should(BeNil()) 212 }) 213 214 }) 215 216 func reconcileBackupWithReturn(r *BackupReconciler, name, ns string) error { 217 wrKey := client.ObjectKey{ 218 Name: name, 219 Namespace: ns, 220 } 221 _, err := r.Reconcile(context.TODO(), reconcile.Request{NamespacedName: wrKey}) 222 return err 223 } 224 225 func tryReconcileBackup(r *BackupReconciler, name, ns string) { 226 wrKey := client.ObjectKey{ 227 Name: name, 228 Namespace: ns, 229 } 230 _, err := r.Reconcile(context.TODO(), reconcile.Request{NamespacedName: wrKey}) 231 if err != nil { 232 By(fmt.Sprintf("reconcile err: %+v ", err)) 233 } 234 Expect(err).Should(BeNil()) 235 }