github.com/oam-dev/kubevela@v1.9.11/pkg/workflow/step/generator_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 step 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/stretchr/testify/assert" 24 "github.com/stretchr/testify/require" 25 v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/runtime" 27 "sigs.k8s.io/controller-runtime/pkg/client/fake" 28 29 workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1" 30 31 "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 32 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1" 33 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 34 common2 "github.com/oam-dev/kubevela/pkg/utils/common" 35 ) 36 37 func TestWorkflowStepGenerator(t *testing.T) { 38 r := require.New(t) 39 cli := fake.NewClientBuilder().WithScheme(common2.Scheme).WithObjects(&workflowv1alpha1.Workflow{ 40 ObjectMeta: v1.ObjectMeta{ 41 Name: "ref-wf", 42 Namespace: "test", 43 }, 44 WorkflowSpec: workflowv1alpha1.WorkflowSpec{ 45 Steps: []workflowv1alpha1.WorkflowStep{{ 46 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 47 Name: "manual-approve", 48 Type: "suspend", 49 }, 50 }, { 51 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 52 Name: "deploy", 53 Type: "deploy", 54 }, 55 }}, 56 }, 57 }).Build() 58 testCases := map[string]struct { 59 input []workflowv1alpha1.WorkflowStep 60 app *v1beta1.Application 61 output []workflowv1alpha1.WorkflowStep 62 hasError bool 63 }{ 64 "apply-component-with-existing-steps": { 65 input: []workflowv1alpha1.WorkflowStep{{ 66 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 67 Name: "example-comp-1", 68 Type: "apply-component", 69 Properties: &runtime.RawExtension{Raw: []byte(`{"component":"example-comp-1"}`)}, 70 }, 71 }}, 72 app: &v1beta1.Application{ 73 Spec: v1beta1.ApplicationSpec{ 74 Components: []common.ApplicationComponent{{ 75 Name: "example-comp-1", 76 }, { 77 Name: "example-comp-2", 78 }}, 79 }, 80 }, 81 output: []workflowv1alpha1.WorkflowStep{{ 82 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 83 Name: "example-comp-1", 84 Type: "apply-component", 85 Properties: &runtime.RawExtension{Raw: []byte(`{"component":"example-comp-1"}`)}, 86 }, 87 }}, 88 }, 89 "apply-component-with-no-steps": { 90 input: []workflowv1alpha1.WorkflowStep{}, 91 app: &v1beta1.Application{ 92 Spec: v1beta1.ApplicationSpec{ 93 Components: []common.ApplicationComponent{{ 94 Name: "example-comp-1", 95 }, { 96 Name: "example-comp-2", 97 }}, 98 }, 99 }, 100 output: []workflowv1alpha1.WorkflowStep{{ 101 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 102 Name: "example-comp-1", 103 Type: "apply-component", 104 Properties: &runtime.RawExtension{Raw: []byte(`{"component":"example-comp-1"}`)}, 105 }, 106 }, { 107 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 108 Name: "example-comp-2", 109 Type: "apply-component", 110 Properties: &runtime.RawExtension{Raw: []byte(`{"component":"example-comp-2"}`)}, 111 }, 112 }}, 113 }, 114 "env-binding-bad": { 115 input: []workflowv1alpha1.WorkflowStep{}, 116 app: &v1beta1.Application{ 117 Spec: v1beta1.ApplicationSpec{ 118 Components: []common.ApplicationComponent{{ 119 Name: "example-comp-1", 120 }}, 121 Policies: []v1beta1.AppPolicy{{ 122 Name: "example-policy", 123 Type: v1alpha1.EnvBindingPolicyType, 124 Properties: &runtime.RawExtension{Raw: []byte(`bad value`)}, 125 }}, 126 }, 127 }, 128 hasError: true, 129 }, 130 "env-binding-correct": { 131 input: []workflowv1alpha1.WorkflowStep{}, 132 app: &v1beta1.Application{ 133 Spec: v1beta1.ApplicationSpec{ 134 Components: []common.ApplicationComponent{{ 135 Name: "example-comp-1", 136 }}, 137 Policies: []v1beta1.AppPolicy{{ 138 Name: "example-policy", 139 Type: v1alpha1.EnvBindingPolicyType, 140 Properties: &runtime.RawExtension{Raw: []byte(`{"envs":[{"name":"env-1"},{"name":"env-2"}]}`)}, 141 }}, 142 }, 143 }, 144 output: []workflowv1alpha1.WorkflowStep{{ 145 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 146 Name: "deploy-example-policy-env-1", 147 Type: "deploy2env", 148 Properties: &runtime.RawExtension{Raw: []byte(`{"env":"env-1","policy":"example-policy"}`)}, 149 }, 150 }, { 151 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 152 Name: "deploy-example-policy-env-2", 153 Type: "deploy2env", 154 Properties: &runtime.RawExtension{Raw: []byte(`{"env":"env-2","policy":"example-policy"}`)}, 155 }, 156 }}, 157 }, 158 "deploy-workflow": { 159 input: []workflowv1alpha1.WorkflowStep{}, 160 app: &v1beta1.Application{ 161 Spec: v1beta1.ApplicationSpec{ 162 Components: []common.ApplicationComponent{{ 163 Name: "example-comp-1", 164 }}, 165 Policies: []v1beta1.AppPolicy{{ 166 Name: "example-topology-policy-1", 167 Type: v1alpha1.TopologyPolicyType, 168 }, { 169 Name: "example-topology-policy-2", 170 Type: v1alpha1.TopologyPolicyType, 171 }, { 172 Name: "example-override-policy-1", 173 Type: v1alpha1.OverridePolicyType, 174 }, { 175 Name: "example-override-policy-2", 176 Type: v1alpha1.OverridePolicyType, 177 }}, 178 }, 179 }, 180 output: []workflowv1alpha1.WorkflowStep{{ 181 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 182 Name: "deploy-example-topology-policy-1", 183 Type: "deploy", 184 Properties: &runtime.RawExtension{Raw: []byte(`{"policies":["example-override-policy-1","example-override-policy-2","example-topology-policy-1"]}`)}, 185 }, 186 }, { 187 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 188 Name: "deploy-example-topology-policy-2", 189 Type: "deploy", 190 Properties: &runtime.RawExtension{Raw: []byte(`{"policies":["example-override-policy-1","example-override-policy-2","example-topology-policy-2"]}`)}, 191 }, 192 }}, 193 }, 194 "deploy-with-ref-without-po-workflow": { 195 input: []workflowv1alpha1.WorkflowStep{}, 196 app: &v1beta1.Application{ 197 Spec: v1beta1.ApplicationSpec{ 198 Components: []common.ApplicationComponent{{ 199 Name: "example-comp", 200 Type: "ref-objects", 201 }}, 202 }, 203 }, 204 output: []workflowv1alpha1.WorkflowStep{{ 205 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 206 Name: "deploy", 207 Type: "deploy", 208 Properties: &runtime.RawExtension{Raw: []byte(`{"policies":[]}`)}, 209 }, 210 }}, 211 }, 212 "ref-workflow": { 213 input: nil, 214 app: &v1beta1.Application{ 215 ObjectMeta: v1.ObjectMeta{ 216 Namespace: "test", 217 }, 218 Spec: v1beta1.ApplicationSpec{ 219 Workflow: &v1beta1.Workflow{ 220 Ref: "ref-wf", 221 }, 222 }, 223 }, 224 output: []workflowv1alpha1.WorkflowStep{{ 225 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 226 Name: "manual-approve", 227 Type: "suspend", 228 }, 229 }, { 230 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 231 Name: "deploy", 232 Type: "deploy", 233 }, 234 }}, 235 }, 236 "ref-workflow-conflict": { 237 input: []workflowv1alpha1.WorkflowStep{{ 238 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 239 Name: "deploy", 240 Type: "deploy", 241 }, 242 }}, 243 app: &v1beta1.Application{ 244 ObjectMeta: v1.ObjectMeta{ 245 Namespace: "test", 246 }, 247 Spec: v1beta1.ApplicationSpec{ 248 Workflow: &v1beta1.Workflow{ 249 Ref: "ref-wf", 250 Steps: []workflowv1alpha1.WorkflowStep{{ 251 WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{ 252 Name: "deploy", 253 Type: "deploy", 254 }, 255 }}, 256 }, 257 }, 258 }, 259 hasError: true, 260 }, 261 "ref-workflow-not-found": { 262 input: nil, 263 app: &v1beta1.Application{ 264 ObjectMeta: v1.ObjectMeta{ 265 Namespace: "test", 266 }, 267 Spec: v1beta1.ApplicationSpec{ 268 Workflow: &v1beta1.Workflow{ 269 Ref: "ref-wf-404", 270 }, 271 }, 272 }, 273 hasError: true, 274 }, 275 } 276 generator := NewChainWorkflowStepGenerator( 277 &RefWorkflowStepGenerator{Context: context.Background(), Client: cli}, 278 &DeployWorkflowStepGenerator{}, 279 &Deploy2EnvWorkflowStepGenerator{}, 280 &ApplyComponentWorkflowStepGenerator{}, 281 ) 282 for name, testCase := range testCases { 283 t.Run(name, func(t *testing.T) { 284 output, err := generator.Generate(testCase.app, testCase.input) 285 if testCase.hasError { 286 r.Error(err) 287 } else { 288 r.NoError(err) 289 r.Equal(testCase.output, output) 290 } 291 }) 292 } 293 } 294 295 func TestIsBuiltinWorkflowStepType(t *testing.T) { 296 assert.True(t, IsBuiltinWorkflowStepType("suspend")) 297 assert.True(t, IsBuiltinWorkflowStepType("apply-component")) 298 assert.True(t, IsBuiltinWorkflowStepType("step-group")) 299 assert.True(t, IsBuiltinWorkflowStepType("builtin-apply-component")) 300 }