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