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  }