github.com/kubevela/workflow@v0.6.0/pkg/providers/util/util_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 util 18 19 import ( 20 "context" 21 "encoding/json" 22 "errors" 23 "fmt" 24 "testing" 25 26 "github.com/stretchr/testify/require" 27 corev1 "k8s.io/api/core/v1" 28 "sigs.k8s.io/yaml" 29 30 monitorContext "github.com/kubevela/pkg/monitor/context" 31 32 wfContext "github.com/kubevela/workflow/pkg/context" 33 "github.com/kubevela/workflow/pkg/cue/model" 34 "github.com/kubevela/workflow/pkg/cue/model/value" 35 "github.com/kubevela/workflow/pkg/cue/process" 36 "github.com/kubevela/workflow/pkg/providers" 37 ) 38 39 func TestPatchK8sObject(t *testing.T) { 40 testcases := map[string]struct { 41 value string 42 expectedErr error 43 patchResult string 44 }{ 45 "test patch k8s object": { 46 value: ` 47 value: { 48 apiVersion: "apps/v1" 49 kind: "Deployment" 50 spec: template: metadata: { 51 labels: { 52 "oam.dev/name": "test" 53 } 54 } 55 } 56 patch: { 57 spec: template: metadata: { 58 labels: { 59 "test-label": "true" 60 } 61 } 62 } 63 `, 64 expectedErr: nil, 65 patchResult: ` 66 apiVersion: "apps/v1" 67 kind: "Deployment" 68 spec: template: metadata: { 69 labels: { 70 "oam.dev/name": "test" 71 "test-label": "true" 72 } 73 } 74 `, 75 }, 76 "test patch k8s object with patchKey": { 77 value: ` 78 value: { 79 apiVersion: "apps/v1" 80 kind: "Deployment" 81 spec: template: spec: { 82 containers: [{ 83 name: "test" 84 }] 85 } 86 } 87 patch: { 88 spec: template: spec: { 89 // +patchKey=name 90 containers: [{ 91 name: "test" 92 env: [{ 93 name: "test-env" 94 value: "test-value" 95 }] 96 }] 97 } 98 } 99 `, 100 expectedErr: nil, 101 patchResult: ` 102 apiVersion: "apps/v1" 103 kind: "Deployment" 104 spec: template: spec: { 105 containers: [{ 106 name: "test" 107 env: [{ 108 name: "test-env" 109 value: "test-value" 110 }] 111 }] 112 } 113 `, 114 }, 115 "test patch k8s object with patchStrategy": { 116 value: ` 117 value: { 118 apiVersion: "apps/v1" 119 kind: "Deployment" 120 spec: template: metadata: { 121 name: "test-name" 122 } 123 } 124 patch: { 125 // +patchStrategy=retainKeys 126 spec: template: metadata: { 127 name: "test-patchStrategy" 128 } 129 } 130 `, 131 expectedErr: nil, 132 patchResult: ` 133 apiVersion: "apps/v1" 134 kind: "Deployment" 135 spec: template: metadata: { 136 name: "test-patchStrategy" 137 } 138 `, 139 }, 140 } 141 142 for name, tc := range testcases { 143 t.Run(name, func(t *testing.T) { 144 r := require.New(t) 145 v, err := value.NewValue(tc.value, nil, "") 146 r.NoError(err) 147 prd := &provider{} 148 err = prd.PatchK8sObject(nil, nil, v, nil) 149 if tc.expectedErr != nil { 150 r.Equal(tc.expectedErr.Error(), err.Error()) 151 return 152 } 153 r.NoError(err) 154 result, err := v.LookupValue("result") 155 r.NoError(err) 156 var patchResult map[string]interface{} 157 r.NoError(result.UnmarshalTo(&patchResult)) 158 var expectResult map[string]interface{} 159 resultValue, err := value.NewValue(tc.patchResult, nil, "") 160 r.NoError(err) 161 r.NoError(resultValue.UnmarshalTo(&expectResult)) 162 r.Equal(expectResult, patchResult) 163 }) 164 } 165 } 166 167 func TestConvertString(t *testing.T) { 168 testCases := map[string]struct { 169 from string 170 expected string 171 expectedErr error 172 }{ 173 "success": { 174 from: `bt: 'test'`, 175 expected: "test", 176 }, 177 "fail": { 178 from: `bt: 123`, 179 expectedErr: errors.New("bt: cannot use value 123 (type int) as (string|bytes)"), 180 }, 181 } 182 183 for name, tc := range testCases { 184 t.Run(name, func(t *testing.T) { 185 r := require.New(t) 186 v, err := value.NewValue(tc.from, nil, "") 187 r.NoError(err) 188 prd := &provider{} 189 err = prd.String(nil, nil, v, nil) 190 if tc.expectedErr != nil { 191 r.Equal(tc.expectedErr.Error(), err.Error()) 192 return 193 } 194 r.NoError(err) 195 expected, err := v.LookupValue("str") 196 r.NoError(err) 197 ret, err := expected.CueValue().String() 198 r.NoError(err) 199 r.Equal(ret, tc.expected) 200 }) 201 } 202 } 203 204 func TestLog(t *testing.T) { 205 wfCtx := newWorkflowContextForTest(t) 206 pCtx := process.NewContext(process.ContextData{}) 207 pCtx.PushData(model.ContextStepName, "test-step") 208 prd := &provider{pCtx: pCtx} 209 logCtx := monitorContext.NewTraceContext(context.Background(), "") 210 211 testCases := []struct { 212 value string 213 expected string 214 expectedErr string 215 }{ 216 { 217 value: `data: "test"`, 218 expected: `{"test-step":{"data":true}}`, 219 }, 220 { 221 value: ` 222 data: { 223 message: "test" 224 } 225 level: 3`, 226 expected: `{"test-step":{"data":true}}`, 227 }, 228 { 229 value: `test: ""`, 230 expected: `{"test-step":{"data":true}}`, 231 }, 232 { 233 value: ` 234 source: { 235 url: "https://kubevela.io" 236 } 237 `, 238 expected: `{"test-step":{"data":true,"source":{"url":"https://kubevela.io"}}}`, 239 }, 240 { 241 value: ` 242 source: { 243 resources: [{ 244 labelSelector: {"test": "test"} 245 }] 246 } 247 `, 248 expected: `{"test-step":{"data":true,"source":{"url":"https://kubevela.io","resources":[{"labelSelector":{"test":"test"}}]}}}`, 249 }, 250 { 251 value: ` 252 source: { 253 resources: [{ 254 name: "test" 255 namespace: "test" 256 cluster: "test" 257 }] 258 } 259 `, 260 expected: `{"test-step":{"data":true,"source":{"url":"https://kubevela.io","resources":[{"name":"test","namespace":"test","cluster":"test"}]}}}`, 261 }, 262 { 263 value: ` 264 source: { 265 url: "https://kubevela.com" 266 } 267 `, 268 expected: `{"test-step":{"data":true,"source":{"url":"https://kubevela.com","resources":[{"name":"test","namespace":"test","cluster":"test"}]}}}`, 269 }, 270 } 271 for i, tc := range testCases { 272 t.Run(fmt.Sprint(i), func(t *testing.T) { 273 r := require.New(t) 274 v, err := value.NewValue(tc.value, nil, "") 275 r.NoError(err) 276 err = prd.Log(logCtx, wfCtx, v, nil) 277 if tc.expectedErr != "" { 278 r.Contains(err.Error(), tc.expectedErr) 279 return 280 } 281 r.NoError(err) 282 if tc.expected != "" { 283 config := wfCtx.GetMutableValue("logConfig") 284 r.Equal(tc.expected, config) 285 } 286 }) 287 } 288 } 289 290 func TestInstall(t *testing.T) { 291 p := providers.NewProviders() 292 pCtx := process.NewContext(process.ContextData{}) 293 pCtx.PushData(model.ContextStepName, "test-step") 294 Install(p, pCtx) 295 h, ok := p.GetHandler("util", "string") 296 r := require.New(t) 297 r.Equal(ok, true) 298 r.Equal(h != nil, true) 299 } 300 301 func newWorkflowContextForTest(t *testing.T) wfContext.Context { 302 cm := corev1.ConfigMap{} 303 r := require.New(t) 304 testCaseJson, err := yaml.YAMLToJSON([]byte(testCaseYaml)) 305 r.NoError(err) 306 err = json.Unmarshal(testCaseJson, &cm) 307 r.NoError(err) 308 309 wfCtx := new(wfContext.WorkflowContext) 310 err = wfCtx.LoadFromConfigMap(cm) 311 r.NoError(err) 312 return wfCtx 313 } 314 315 var ( 316 testCaseYaml = `apiVersion: v1 317 data: 318 logConfig: "" 319 kind: ConfigMap 320 metadata: 321 name: app-v1 322 ` 323 )