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  }