github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/initializer/analyze/analyze_test.go (about) 1 /* 2 Copyright 2020 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 analyze 18 19 import ( 20 "context" 21 "fmt" 22 "strings" 23 "testing" 24 25 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/build/jib" 26 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/config" 27 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker" 28 initconfig "github.com/GoogleContainerTools/skaffold/pkg/skaffold/initializer/config" 29 "github.com/GoogleContainerTools/skaffold/testutil" 30 ) 31 32 type builder struct { 33 name string 34 path string 35 } 36 37 func TestAnalyze(t *testing.T) { 38 emptyFile := "" 39 largeFile := "" 40 for i := 1; i < 1000; i++ { 41 largeFile = fmt.Sprintf("%s0", largeFile) 42 } 43 validK8sManifest := "apiVersion: v1\nkind: Service\nmetadata:\n name: test\n" 44 45 tests := []struct { 46 description string 47 filesWithContents map[string]string 48 expectedConfigs []string 49 expectedBuilders []builder 50 config initconfig.Config 51 shouldErr bool 52 }{ 53 { 54 description: "should return correct k8 configs and build files (backwards compatibility)", 55 filesWithContents: map[string]string{ 56 "config/test.yaml": validK8sManifest, 57 "config/invalid.yaml": emptyFile, 58 "k8pod.yml": validK8sManifest, 59 "README": emptyFile, 60 "deploy/Dockerfile": emptyFile, 61 "deploy/Dockerfile.dev": emptyFile, 62 "deploy/dev.Dockerfile": emptyFile, 63 "deploy/test.dockerfile": emptyFile, 64 "gradle/build.gradle": emptyFile, 65 "maven/pom.xml": emptyFile, 66 "Dockerfile": emptyFile, 67 }, 68 config: initconfig.Config{ 69 Force: false, 70 EnableBuildpacksInit: false, 71 EnableJibInit: false, 72 }, 73 expectedConfigs: []string{ 74 "k8pod.yml", 75 "config/test.yaml", 76 }, 77 expectedBuilders: []builder{ 78 {name: "Docker", path: "Dockerfile"}, 79 {name: "Docker", path: "deploy/Dockerfile"}, 80 {name: "Docker", path: "deploy/Dockerfile.dev"}, 81 {name: "Docker", path: "deploy/dev.Dockerfile"}, 82 {name: "Docker", path: "deploy/test.dockerfile"}, 83 }, 84 shouldErr: false, 85 }, 86 { 87 description: "--skip-build should return no builders in analysis", 88 filesWithContents: map[string]string{ 89 "config/test.yaml": validK8sManifest, 90 "config/invalid.yaml": emptyFile, 91 "k8pod.yml": validK8sManifest, 92 "README": emptyFile, 93 "deploy/Dockerfile": emptyFile, 94 "deploy/Dockerfile.dev": emptyFile, 95 "deploy/dev.Dockerfile": emptyFile, 96 "deploy/test.dockerfile": emptyFile, 97 "gradle/build.gradle": emptyFile, 98 "maven/pom.xml": emptyFile, 99 "Dockerfile": emptyFile, 100 }, 101 config: initconfig.Config{ 102 Force: false, 103 EnableBuildpacksInit: false, 104 EnableJibInit: false, 105 SkipBuild: true, 106 }, 107 expectedConfigs: []string{ 108 "k8pod.yml", 109 "config/test.yaml", 110 }, 111 expectedBuilders: nil, 112 shouldErr: false, 113 }, 114 { 115 description: "should return correct k8 configs and build files", 116 filesWithContents: map[string]string{ 117 "config/test.yaml": validK8sManifest, 118 "config/invalid.yaml": emptyFile, 119 "k8pod.yml": validK8sManifest, 120 "README": emptyFile, 121 "deploy/Dockerfile": emptyFile, 122 "gradle/build.gradle": emptyFile, 123 "maven/pom.xml": emptyFile, 124 "Dockerfile": emptyFile, 125 "node/package.json": emptyFile, 126 }, 127 config: initconfig.Config{ 128 Force: false, 129 EnableBuildpacksInit: true, 130 EnableJibInit: true, 131 EnableJibGradleInit: true, 132 }, 133 expectedConfigs: []string{ 134 "k8pod.yml", 135 "config/test.yaml", 136 }, 137 expectedBuilders: []builder{ 138 {name: "Docker", path: "Dockerfile"}, 139 {name: "Docker", path: "deploy/Dockerfile"}, 140 {name: "Jib Gradle Plugin", path: "gradle/build.gradle"}, 141 {name: "Buildpacks", path: "gradle/build.gradle"}, 142 {name: "Jib Maven Plugin", path: "maven/pom.xml"}, 143 {name: "Buildpacks", path: "maven/pom.xml"}, 144 {name: "Buildpacks", path: "node/package.json"}, 145 }, 146 shouldErr: false, 147 }, 148 { 149 description: "skip validating nested jib configs", 150 filesWithContents: map[string]string{ 151 "config/test.yaml": validK8sManifest, 152 "k8pod.yml": validK8sManifest, 153 "gradle/build.gradle": emptyFile, 154 "gradle/subproject/build.gradle": emptyFile, 155 "gradle/subproject/Dockerfile": emptyFile, 156 "maven/asubproject/pom.xml": emptyFile, 157 "maven/asubproject/Dockerfile": emptyFile, 158 "maven/pom.xml": emptyFile, 159 }, 160 config: initconfig.Config{ 161 Force: false, 162 EnableBuildpacksInit: false, 163 EnableJibInit: true, 164 EnableJibGradleInit: true, 165 }, 166 expectedConfigs: []string{ 167 "k8pod.yml", 168 "config/test.yaml", 169 }, 170 expectedBuilders: []builder{ 171 {name: "Jib Gradle Plugin", path: "gradle/build.gradle"}, 172 {name: "Docker", path: "gradle/subproject/Dockerfile"}, 173 {name: "Jib Maven Plugin", path: "maven/pom.xml"}, 174 {name: "Docker", path: "maven/asubproject/Dockerfile"}, 175 }, 176 shouldErr: false, 177 }, 178 { 179 description: "multiple builders in same directory", 180 filesWithContents: map[string]string{ 181 "build.gradle": emptyFile, 182 "ignored-builder/build.gradle": emptyFile, 183 "not-ignored-config/test.yaml": validK8sManifest, 184 "Dockerfile": emptyFile, 185 "k8pod.yml": validK8sManifest, 186 "pom.xml": emptyFile, 187 }, 188 config: initconfig.Config{ 189 Force: false, 190 EnableBuildpacksInit: false, 191 EnableJibInit: true, 192 EnableJibGradleInit: true, 193 }, 194 expectedConfigs: []string{ 195 "k8pod.yml", 196 "not-ignored-config/test.yaml", 197 }, 198 expectedBuilders: []builder{ 199 {name: "Docker", path: "Dockerfile"}, 200 {name: "Jib Gradle Plugin", path: "build.gradle"}, 201 {name: "Jib Maven Plugin", path: "pom.xml"}, 202 }, 203 shouldErr: false, 204 }, 205 { 206 description: "should skip jib gradle", 207 filesWithContents: map[string]string{ 208 "build.gradle": emptyFile, 209 "pom.xml": emptyFile, 210 }, 211 config: initconfig.Config{ 212 Force: false, 213 EnableBuildpacksInit: false, 214 EnableJibInit: true, 215 EnableJibGradleInit: false, 216 }, 217 expectedConfigs: nil, 218 expectedBuilders: []builder{ 219 {name: "Jib Maven Plugin", path: "pom.xml"}, 220 }, 221 shouldErr: false, 222 }, 223 { 224 description: "should skip hidden dir", 225 filesWithContents: map[string]string{ 226 ".hidden/test.yaml": validK8sManifest, 227 "k8pod.yml": validK8sManifest, 228 "README": emptyFile, 229 ".hidden/Dockerfile": emptyFile, 230 "Dockerfile": emptyFile, 231 }, 232 config: initconfig.Config{ 233 Force: false, 234 EnableBuildpacksInit: false, 235 EnableJibInit: true, 236 }, 237 expectedConfigs: []string{ 238 "k8pod.yml", 239 }, 240 expectedBuilders: []builder{ 241 {name: "Docker", path: "Dockerfile"}, 242 }, 243 shouldErr: false, 244 }, 245 { 246 description: "should skip vendor folder", 247 filesWithContents: map[string]string{ 248 "Dockerfile": emptyFile, 249 "vendor/Dockerfile": emptyFile, 250 "vendor/pom.xml": emptyFile, 251 "vendor/package.json": emptyFile, 252 "sub/vendor/Dockerfile": emptyFile, 253 }, 254 config: initconfig.Config{ 255 Force: false, 256 EnableBuildpacksInit: true, 257 EnableJibInit: true, 258 }, 259 expectedBuilders: []builder{ 260 {name: "Docker", path: "Dockerfile"}, 261 }, 262 shouldErr: false, 263 }, 264 { 265 description: "should skip node_modules folder", 266 filesWithContents: map[string]string{ 267 "Dockerfile": emptyFile, 268 "node_modules/Dockerfile": emptyFile, 269 "node_modules/pom.xml": emptyFile, 270 "node_modules/package.json": emptyFile, 271 "sub/node_modules/Dockerfile": emptyFile, 272 }, 273 config: initconfig.Config{ 274 Force: false, 275 EnableBuildpacksInit: true, 276 EnableJibInit: true, 277 }, 278 expectedBuilders: []builder{ 279 {name: "Docker", path: "Dockerfile"}, 280 }, 281 shouldErr: false, 282 }, 283 { 284 description: "should skip large files", 285 filesWithContents: map[string]string{ 286 "k8pod.yml": validK8sManifest, 287 "README": emptyFile, 288 "Dockerfile": emptyFile, 289 "largeFileDir/Dockerfile": largeFile, 290 }, 291 config: initconfig.Config{ 292 Force: false, 293 EnableBuildpacksInit: false, 294 EnableJibInit: true, 295 MaxFileSize: 100, 296 }, 297 expectedConfigs: []string{ 298 "k8pod.yml", 299 }, 300 expectedBuilders: []builder{ 301 {name: "Docker", path: "Dockerfile"}, 302 }, 303 shouldErr: false, 304 }, 305 { 306 description: "should not error when skaffold.config present and force = true", 307 filesWithContents: map[string]string{ 308 "skaffold.yaml": `apiVersion: skaffold/v1beta6 309 kind: Config 310 deploy: 311 kustomize: {}`, 312 "config/test.yaml": validK8sManifest, 313 "k8pod.yml": validK8sManifest, 314 "README": emptyFile, 315 "deploy/Dockerfile": emptyFile, 316 "Dockerfile": emptyFile, 317 }, 318 config: initconfig.Config{ 319 Force: true, 320 EnableBuildpacksInit: false, 321 EnableJibInit: true, 322 }, 323 expectedConfigs: []string{ 324 "k8pod.yml", 325 "config/test.yaml", 326 }, 327 expectedBuilders: []builder{ 328 {name: "Docker", path: "Dockerfile"}, 329 {name: "Docker", path: "deploy/Dockerfile"}, 330 }, 331 shouldErr: false, 332 }, 333 { 334 description: "should error when skaffold.config present and force = false", 335 filesWithContents: map[string]string{ 336 "config/test.yaml": validK8sManifest, 337 "k8pod.yml": validK8sManifest, 338 "README": emptyFile, 339 "deploy/Dockerfile": emptyFile, 340 "Dockerfile": emptyFile, 341 "skaffold.yaml": `apiVersion: skaffold/v1beta6 342 kind: Config 343 deploy: 344 kustomize: {}`, 345 }, 346 config: initconfig.Config{ 347 Force: false, 348 EnableBuildpacksInit: false, 349 EnableJibInit: true, 350 Opts: config.SkaffoldOptions{ 351 ConfigurationFile: "skaffold.yaml", 352 }, 353 }, 354 expectedConfigs: nil, 355 expectedBuilders: nil, 356 shouldErr: true, 357 }, 358 { 359 description: "should error when skaffold.config present with jib config", 360 filesWithContents: map[string]string{ 361 "config/test.yaml": validK8sManifest, 362 "k8pod.yml": validK8sManifest, 363 "README": emptyFile, 364 "pom.xml": emptyFile, 365 "skaffold.yaml": `apiVersion: skaffold/v1beta6 366 kind: Config 367 deploy: 368 kustomize: {}`, 369 }, 370 config: initconfig.Config{ 371 Force: false, 372 EnableBuildpacksInit: false, 373 EnableJibInit: true, 374 Opts: config.SkaffoldOptions{ 375 ConfigurationFile: "skaffold.yaml", 376 }, 377 }, 378 expectedConfigs: nil, 379 expectedBuilders: nil, 380 shouldErr: true, 381 }, 382 } 383 for _, test := range tests { 384 testutil.Run(t, test.description, func(t *testutil.T) { 385 t.NewTempDir().WriteFiles(test.filesWithContents).Chdir() 386 387 t.Override(&docker.Validate, fakeValidateDockerfile) 388 t.Override(&jib.Validate, fakeValidateJibConfig) 389 390 a := NewAnalyzer(test.config) 391 err := a.Analyze(".") 392 393 t.CheckError(test.shouldErr, err) 394 if test.shouldErr { 395 return 396 } 397 398 t.CheckDeepEqual(test.expectedConfigs, a.Manifests()) 399 400 if len(test.expectedBuilders) != len(a.Builders()) { 401 t.Fatalf("expected %d builders, got %d: %v", 402 len(test.expectedBuilders), 403 len(a.Builders()), a.Builders()) 404 } 405 for i := range a.Builders() { 406 t.CheckDeepEqual(test.expectedBuilders[i].name, a.Builders()[i].Name()) 407 t.CheckDeepEqual(test.expectedBuilders[i].path, a.Builders()[i].Path()) 408 } 409 }) 410 } 411 } 412 413 func fakeValidateDockerfile(path string) bool { 414 return strings.Contains(strings.ToLower(path), "dockerfile") 415 } 416 417 func fakeValidateJibConfig(_ context.Context, path string, enableGradle bool) []jib.ArtifactConfig { 418 if strings.HasSuffix(path, "build.gradle") && enableGradle { 419 return []jib.ArtifactConfig{{BuilderName: jib.PluginName(jib.JibGradle), File: path}} 420 } 421 if strings.HasSuffix(path, "pom.xml") { 422 return []jib.ArtifactConfig{{BuilderName: jib.PluginName(jib.JibMaven), File: path}} 423 } 424 return nil 425 }