github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/inspect/buildEnv/add_cluster_test.go (about) 1 /* 2 Copyright 2021 The Skaffold 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 inspect 18 19 import ( 20 "bytes" 21 "context" 22 "errors" 23 "fmt" 24 "testing" 25 26 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/config" 27 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/inspect" 28 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/parser" 29 sErrors "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/errors" 30 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest" 31 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/util/stringslice" 32 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/yaml" 33 "github.com/GoogleContainerTools/skaffold/testutil" 34 ) 35 36 func TestAddClusterBuildEnv(t *testing.T) { 37 tests := []struct { 38 description string 39 profile string 40 modules []string 41 buildEnvOpts inspect.BuildEnvOptions 42 expectedConfigs []string 43 err error 44 expectedErrMsg string 45 }{ 46 { 47 description: "add to default pipeline", 48 buildEnvOpts: inspect.BuildEnvOptions{RunAsUser: -1, PullSecretPath: "path/to/secret", DockerConfigPath: "path/to/docker/config", Timeout: "128", Concurrency: 2}, 49 expectedConfigs: []string{ 50 `apiVersion: "" 51 kind: "" 52 metadata: 53 name: cfg1_0 54 build: 55 cluster: 56 concurrency: 2 57 dockerConfig: 58 path: path/to/docker/config 59 pullSecretPath: path/to/secret 60 timeout: "128" 61 profiles: 62 - name: p1 63 build: 64 cluster: {} 65 --- 66 apiVersion: "" 67 kind: "" 68 metadata: 69 name: cfg1_1 70 requires: 71 - path: path/to/cfg2 72 build: 73 cluster: 74 concurrency: 2 75 dockerConfig: 76 path: path/to/docker/config 77 pullSecretPath: path/to/secret 78 timeout: "128" 79 profiles: 80 - name: p1 81 build: 82 cluster: {} 83 `, ``, 84 }, 85 }, 86 { 87 description: "add to existing profile", 88 profile: "p1", 89 buildEnvOpts: inspect.BuildEnvOptions{RunAsUser: -1, PullSecretPath: "path/to/secret", DockerConfigPath: "path/to/docker/config", Timeout: "128", Concurrency: 2}, 90 expectedConfigs: []string{ 91 `apiVersion: "" 92 kind: "" 93 metadata: 94 name: cfg1_0 95 build: 96 local: {} 97 profiles: 98 - name: p1 99 build: 100 cluster: 101 concurrency: 2 102 dockerConfig: 103 path: path/to/docker/config 104 pullSecretPath: path/to/secret 105 timeout: "128" 106 --- 107 apiVersion: "" 108 kind: "" 109 metadata: 110 name: cfg1_1 111 requires: 112 - path: path/to/cfg2 113 activeProfiles: 114 - name: p1 115 activatedBy: 116 - p1 117 build: 118 local: {} 119 profiles: 120 - name: p1 121 build: 122 cluster: 123 concurrency: 2 124 dockerConfig: 125 path: path/to/docker/config 126 pullSecretPath: path/to/secret 127 timeout: "128" 128 `, `apiVersion: "" 129 kind: "" 130 metadata: 131 name: cfg2 132 build: 133 googleCloudBuild: {} 134 profiles: 135 - name: p1 136 build: 137 cluster: 138 concurrency: 2 139 dockerConfig: 140 path: path/to/docker/config 141 pullSecretPath: path/to/secret 142 timeout: "128" 143 `, 144 }, 145 }, 146 { 147 description: "add to new profile", 148 profile: "p2", 149 buildEnvOpts: inspect.BuildEnvOptions{RunAsUser: -1, PullSecretPath: "path/to/secret", DockerConfigPath: "path/to/docker/config", Timeout: "128", Concurrency: 2}, 150 expectedConfigs: []string{ 151 `apiVersion: "" 152 kind: "" 153 metadata: 154 name: cfg1_0 155 build: 156 local: {} 157 profiles: 158 - name: p1 159 build: 160 cluster: {} 161 - name: p2 162 build: 163 cluster: 164 concurrency: 2 165 dockerConfig: 166 path: path/to/docker/config 167 pullSecretPath: path/to/secret 168 timeout: "128" 169 --- 170 apiVersion: "" 171 kind: "" 172 metadata: 173 name: cfg1_1 174 requires: 175 - path: path/to/cfg2 176 activeProfiles: 177 - name: p2 178 activatedBy: 179 - p2 180 build: 181 local: {} 182 profiles: 183 - name: p1 184 build: 185 cluster: {} 186 - name: p2 187 build: 188 cluster: 189 concurrency: 2 190 dockerConfig: 191 path: path/to/docker/config 192 pullSecretPath: path/to/secret 193 timeout: "128" 194 `, `apiVersion: "" 195 kind: "" 196 metadata: 197 name: cfg2 198 build: 199 googleCloudBuild: {} 200 profiles: 201 - name: p1 202 build: 203 local: {} 204 - name: p2 205 build: 206 cluster: 207 concurrency: 2 208 dockerConfig: 209 path: path/to/docker/config 210 pullSecretPath: path/to/secret 211 timeout: "128" 212 `, 213 }, 214 }, 215 { 216 description: "add to new profile in selected modules", 217 modules: []string{"cfg1_1"}, 218 profile: "p2", 219 buildEnvOpts: inspect.BuildEnvOptions{RunAsUser: -1, PullSecretPath: "path/to/secret", DockerConfigPath: "path/to/docker/config", Timeout: "128", Concurrency: 2}, 220 expectedConfigs: []string{ 221 `apiVersion: "" 222 kind: "" 223 metadata: 224 name: cfg1_0 225 build: 226 local: {} 227 profiles: 228 - name: p1 229 build: 230 cluster: {} 231 --- 232 apiVersion: "" 233 kind: "" 234 metadata: 235 name: cfg1_1 236 requires: 237 - path: path/to/cfg2 238 activeProfiles: 239 - name: p2 240 activatedBy: 241 - p2 242 build: 243 local: {} 244 profiles: 245 - name: p1 246 build: 247 cluster: {} 248 - name: p2 249 build: 250 cluster: 251 concurrency: 2 252 dockerConfig: 253 path: path/to/docker/config 254 pullSecretPath: path/to/secret 255 timeout: "128" 256 `, `apiVersion: "" 257 kind: "" 258 metadata: 259 name: cfg2 260 build: 261 googleCloudBuild: {} 262 profiles: 263 - name: p1 264 build: 265 local: {} 266 - name: p2 267 build: 268 cluster: 269 concurrency: 2 270 dockerConfig: 271 path: path/to/docker/config 272 pullSecretPath: path/to/secret 273 timeout: "128" 274 `, "", 275 }, 276 }, 277 { 278 description: "add to new profile in nested module", 279 modules: []string{"cfg2"}, 280 profile: "p2", 281 buildEnvOpts: inspect.BuildEnvOptions{RunAsUser: -1, PullSecretPath: "path/to/secret", DockerConfigPath: "path/to/docker/config", Timeout: "128", Concurrency: 2}, 282 expectedConfigs: []string{"", 283 `apiVersion: "" 284 kind: "" 285 metadata: 286 name: cfg2 287 build: 288 googleCloudBuild: {} 289 profiles: 290 - name: p1 291 build: 292 local: {} 293 - name: p2 294 build: 295 cluster: 296 concurrency: 2 297 dockerConfig: 298 path: path/to/docker/config 299 pullSecretPath: path/to/secret 300 timeout: "128" 301 `, 302 }, 303 }, 304 { 305 description: "actionable error", 306 err: sErrors.MainConfigFileNotFoundErr("path/to/skaffold.yaml", fmt.Errorf("failed to read file : %q", "skaffold.yaml")), 307 expectedErrMsg: `{"errorCode":"CONFIG_FILE_NOT_FOUND_ERR","errorMessage":"unable to find configuration file \"path/to/skaffold.yaml\": failed to read file : \"skaffold.yaml\". Check that the specified configuration file exists at \"path/to/skaffold.yaml\"."}` + "\n", 308 }, 309 { 310 description: "generic error", 311 err: errors.New("some error occurred"), 312 expectedErrMsg: `{"errorCode":"INSPECT_UNKNOWN_ERR","errorMessage":"some error occurred"}` + "\n", 313 }, 314 } 315 for _, test := range tests { 316 testutil.Run(t, test.description, func(t *testutil.T) { 317 configSet := parser.SkaffoldConfigSet{ 318 &parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{ 319 Metadata: latest.Metadata{Name: "cfg1_0"}, 320 Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{LocalBuild: &latest.LocalBuild{}}}}, 321 Profiles: []latest.Profile{ 322 {Name: "p1", Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{Cluster: &latest.ClusterDetails{}}}}}, 323 }}, SourceFile: pathToCfg1, IsRootConfig: true, SourceIndex: 0}, 324 &parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{ 325 Metadata: latest.Metadata{Name: "cfg1_1"}, 326 Dependencies: []latest.ConfigDependency{{Path: pathToCfg2}}, 327 Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{LocalBuild: &latest.LocalBuild{}}}}, 328 Profiles: []latest.Profile{ 329 {Name: "p1", Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{Cluster: &latest.ClusterDetails{}}}}}, 330 }}, SourceFile: pathToCfg1, IsRootConfig: true, SourceIndex: 1}, 331 &parser.SkaffoldConfigEntry{SkaffoldConfig: &latest.SkaffoldConfig{ 332 Metadata: latest.Metadata{Name: "cfg2"}, 333 Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{GoogleCloudBuild: &latest.GoogleCloudBuild{}}}}, 334 Profiles: []latest.Profile{ 335 {Name: "p1", Pipeline: latest.Pipeline{Build: latest.BuildConfig{BuildType: latest.BuildType{LocalBuild: &latest.LocalBuild{}}}}}, 336 }}, SourceFile: pathToCfg2, SourceIndex: 0}, 337 } 338 t.Override(&inspect.GetConfigSet, func(ctx context.Context, opts config.SkaffoldOptions) (parser.SkaffoldConfigSet, error) { 339 if test.err != nil { 340 return nil, test.err 341 } 342 var sets parser.SkaffoldConfigSet 343 if len(opts.ConfigurationFilter) == 0 || stringslice.Contains(opts.ConfigurationFilter, "cfg2") || stringslice.Contains(opts.ConfigurationFilter, "cfg1_1") { 344 sets = append(sets, configSet[2]) 345 } 346 if len(opts.ConfigurationFilter) == 0 || stringslice.Contains(opts.ConfigurationFilter, "cfg1_0") { 347 sets = append(sets, configSet[0]) 348 } 349 if len(opts.ConfigurationFilter) == 0 || stringslice.Contains(opts.ConfigurationFilter, "cfg1_1") { 350 sets = append(sets, configSet[1]) 351 } 352 return sets, nil 353 }) 354 t.Override(&inspect.ReadFileFunc, func(filename string) ([]byte, error) { 355 if filename == pathToCfg1 { 356 return yaml.MarshalWithSeparator([]*latest.SkaffoldConfig{configSet[0].SkaffoldConfig, configSet[1].SkaffoldConfig}) 357 } else if filename == pathToCfg2 { 358 return yaml.MarshalWithSeparator([]*latest.SkaffoldConfig{configSet[2].SkaffoldConfig}) 359 } 360 t.FailNow() 361 return nil, nil 362 }) 363 var actualCfg1, actualCfg2 string 364 t.Override(&inspect.WriteFileFunc, func(filename string, data []byte) error { 365 switch filename { 366 case pathToCfg1: 367 actualCfg1 = string(data) 368 case pathToCfg2: 369 actualCfg2 = string(data) 370 default: 371 t.FailNow() 372 } 373 return nil 374 }) 375 376 var buf bytes.Buffer 377 err := AddClusterBuildEnv(context.Background(), &buf, inspect.Options{OutFormat: "json", Modules: test.modules, Profile: test.profile, BuildEnvOptions: test.buildEnvOpts}) 378 t.CheckError(test.err != nil, err) 379 if test.err == nil { 380 t.CheckDeepEqual(test.expectedConfigs[0], actualCfg1, testutil.YamlObj(t.T)) 381 t.CheckDeepEqual(test.expectedConfigs[1], actualCfg2, testutil.YamlObj(t.T)) 382 } else { 383 t.CheckDeepEqual(test.expectedErrMsg, buf.String()) 384 } 385 }) 386 } 387 }