github.com/xgoffin/jenkins-library@v1.154.0/cmd/cnbBuild_test.go (about) 1 package cmd 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "testing" 8 9 "github.com/SAP/jenkins-library/pkg/cnbutils" 10 piperconf "github.com/SAP/jenkins-library/pkg/config" 11 piperhttp "github.com/SAP/jenkins-library/pkg/http" 12 "github.com/SAP/jenkins-library/pkg/mock" 13 "github.com/SAP/jenkins-library/pkg/telemetry" 14 "github.com/jarcoal/httpmock" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 const imageRegistry = "some-registry" 20 21 func newCnbBuildTestsUtils() cnbutils.MockUtils { 22 utils := cnbutils.MockUtils{ 23 ExecMockRunner: &mock.ExecMockRunner{}, 24 FilesMock: &mock.FilesMock{}, 25 } 26 utils.AddFile("/layers/report.toml", []byte(`[build] 27 [image] 28 tags = ["localhost:5000/not-found:0.0.1"] 29 digest = "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec" 30 manifest-size = 2388`)) 31 return utils 32 } 33 34 func addBuilderFiles(utils *cnbutils.MockUtils) { 35 utils.FilesMock.AddFile(creatorPath, []byte(`xyz`)) 36 } 37 38 func assertLifecycleCalls(t *testing.T, runner *mock.ExecMockRunner, callNo int) { 39 require.GreaterOrEqual(t, len(runner.Calls), callNo) 40 assert.Equal(t, creatorPath, runner.Calls[callNo-1].Exec) 41 for _, arg := range []string{"-no-color", "-buildpacks", "/cnb/buildpacks", "-order", "/cnb/order.toml", "-platform", "/tmp/platform"} { 42 assert.Contains(t, runner.Calls[callNo-1].Params, arg) 43 } 44 } 45 46 func TestRunCnbBuild(t *testing.T) { 47 configOptions.openFile = piperconf.OpenPiperFile 48 49 t.Run("prefers direct configuration", func(t *testing.T) { 50 t.Parallel() 51 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 52 config := cnbBuildOptions{ 53 ContainerImageName: "my-image", 54 ContainerImageTag: "0.0.1", 55 ContainerRegistryURL: fmt.Sprintf("https://%s", imageRegistry), 56 DockerConfigJSON: "/path/to/config.json", 57 } 58 59 projectToml := `[project] 60 id = "io.buildpacks.my-app" 61 ` 62 63 utils := newCnbBuildTestsUtils() 64 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 65 utils.FilesMock.AddFile("project.toml", []byte(projectToml)) 66 addBuilderFiles(&utils) 67 68 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 69 70 require.NoError(t, err) 71 runner := utils.ExecMockRunner 72 assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}") 73 assertLifecycleCalls(t, runner, 1) 74 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", imageRegistry, config.ContainerImageName, config.ContainerImageTag)) 75 assert.Equal(t, config.ContainerRegistryURL, commonPipelineEnvironment.container.registryURL) 76 assert.Equal(t, "my-image:0.0.1", commonPipelineEnvironment.container.imageNameTag) 77 }) 78 79 t.Run("prefers project descriptor", func(t *testing.T) { 80 t.Parallel() 81 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 82 config := cnbBuildOptions{ 83 ContainerImageTag: "0.0.1", 84 ContainerRegistryURL: fmt.Sprintf("https://%s", imageRegistry), 85 DockerConfigJSON: "/path/to/config.json", 86 ProjectDescriptor: "project.toml", 87 } 88 89 projectToml := `[project] 90 id = "io.buildpacks.my-app" 91 ` 92 93 utils := newCnbBuildTestsUtils() 94 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 95 utils.FilesMock.AddFile("project.toml", []byte(projectToml)) 96 addBuilderFiles(&utils) 97 98 telemetryData := telemetry.CustomData{} 99 err := callCnbBuild(&config, &telemetryData, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 100 101 require.NoError(t, err) 102 runner := utils.ExecMockRunner 103 assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}") 104 assertLifecycleCalls(t, runner, 1) 105 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", imageRegistry, "io-buildpacks-my-app", config.ContainerImageTag)) 106 assert.Equal(t, config.ContainerRegistryURL, commonPipelineEnvironment.container.registryURL) 107 assert.Equal(t, "io-buildpacks-my-app:0.0.1", commonPipelineEnvironment.container.imageNameTag) 108 109 assert.Equal(t, "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec", commonPipelineEnvironment.container.imageDigest) 110 assert.Contains(t, commonPipelineEnvironment.container.imageDigests, "sha256:52eac630560210e5ae13eb10797c4246d6f02d425f32b9430ca00bde697c79ec") 111 112 customDataAsString := telemetryData.Custom1 113 customData := cnbBuildTelemetry{} 114 err = json.Unmarshal([]byte(customDataAsString), &customData) 115 require.NoError(t, err) 116 assert.Equal(t, 1, len(customData.Data)) 117 assert.Equal(t, "root", string(customData.Data[0].Path)) 118 }) 119 120 t.Run("success case (registry with https)", func(t *testing.T) { 121 t.Parallel() 122 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 123 config := cnbBuildOptions{ 124 ContainerImageName: "my-image", 125 ContainerImageTag: "0.0.1", 126 ContainerRegistryURL: fmt.Sprintf("https://%s", imageRegistry), 127 DockerConfigJSON: "/path/to/config.json", 128 } 129 130 utils := newCnbBuildTestsUtils() 131 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 132 addBuilderFiles(&utils) 133 134 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 135 136 require.NoError(t, err) 137 runner := utils.ExecMockRunner 138 assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}") 139 assertLifecycleCalls(t, runner, 1) 140 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", imageRegistry, config.ContainerImageName, config.ContainerImageTag)) 141 assert.Equal(t, config.ContainerRegistryURL, commonPipelineEnvironment.container.registryURL) 142 assert.Equal(t, "my-image:0.0.1", commonPipelineEnvironment.container.imageNameTag) 143 }) 144 145 t.Run("success case (registry without https)", func(t *testing.T) { 146 t.Parallel() 147 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 148 config := cnbBuildOptions{ 149 ContainerImageName: "my-image", 150 ContainerImageTag: "0.0.1", 151 ContainerRegistryURL: imageRegistry, 152 DockerConfigJSON: "/path/to/config.json", 153 } 154 155 utils := newCnbBuildTestsUtils() 156 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 157 addBuilderFiles(&utils) 158 159 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 160 161 require.NoError(t, err) 162 runner := utils.ExecMockRunner 163 assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}") 164 assertLifecycleCalls(t, runner, 1) 165 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", config.ContainerRegistryURL, config.ContainerImageName, config.ContainerImageTag)) 166 assert.Equal(t, fmt.Sprintf("https://%s", config.ContainerRegistryURL), commonPipelineEnvironment.container.registryURL) 167 assert.Equal(t, "my-image:0.0.1", commonPipelineEnvironment.container.imageNameTag) 168 }) 169 170 t.Run("success case (custom buildpacks and custom env variables, renaming docker conf file, additional tag)", func(t *testing.T) { 171 t.Parallel() 172 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 173 config := cnbBuildOptions{ 174 ContainerImageName: "my-image", 175 ContainerImageTag: "0.0.1", 176 ContainerRegistryURL: imageRegistry, 177 DockerConfigJSON: "/path/to/test.json", 178 Buildpacks: []string{"test"}, 179 BuildEnvVars: map[string]interface{}{ 180 "FOO": "BAR", 181 }, 182 AdditionalTags: []string{"latest"}, 183 } 184 185 utils := newCnbBuildTestsUtils() 186 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 187 addBuilderFiles(&utils) 188 189 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 190 191 require.NoError(t, err) 192 runner := utils.ExecMockRunner 193 assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}") 194 assert.Equal(t, creatorPath, runner.Calls[0].Exec) 195 assert.Contains(t, runner.Calls[0].Params, "/tmp/buildpacks") 196 assert.Contains(t, runner.Calls[0].Params, "/tmp/buildpacks/order.toml") 197 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", config.ContainerRegistryURL, config.ContainerImageName, config.ContainerImageTag)) 198 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:latest", config.ContainerRegistryURL, config.ContainerImageName)) 199 200 initialFileExists, _ := utils.FileExists("/path/to/test.json") 201 renamedFileExists, _ := utils.FileExists("/path/to/config.json") 202 203 assert.False(t, initialFileExists) 204 assert.True(t, renamedFileExists) 205 }) 206 207 t.Run("success case (customTlsCertificates)", func(t *testing.T) { 208 t.Parallel() 209 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 210 httpmock.Activate() 211 defer httpmock.DeactivateAndReset() 212 httpmock.RegisterResponder(http.MethodGet, "https://test-cert.com/cert.crt", httpmock.NewStringResponder(200, "testCert")) 213 client := &piperhttp.Client{} 214 client.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true}) 215 216 caCertsFile := "/etc/ssl/certs/ca-certificates.crt" 217 caCertsTmpFile := "/tmp/ca-certificates.crt" 218 registry := "some-registry" 219 config := cnbBuildOptions{ 220 ContainerImageName: "my-image", 221 ContainerImageTag: "0.0.1", 222 ContainerRegistryURL: registry, 223 DockerConfigJSON: "/path/to/config.json", 224 CustomTLSCertificateLinks: []string{"https://test-cert.com/cert.crt", "https://test-cert.com/cert.crt"}, 225 } 226 227 utils := newCnbBuildTestsUtils() 228 utils.FilesMock.AddFile(caCertsFile, []byte("test\n")) 229 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 230 addBuilderFiles(&utils) 231 232 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, client) 233 require.NoError(t, err) 234 235 result, err := utils.FilesMock.FileRead(caCertsTmpFile) 236 require.NoError(t, err) 237 assert.Equal(t, "test\ntestCert\ntestCert\n", string(result)) 238 239 require.NoError(t, err) 240 runner := utils.ExecMockRunner 241 assert.Contains(t, runner.Env, "CNB_REGISTRY_AUTH={\"my-registry\":\"Basic dXNlcjpwYXNz\"}") 242 assert.Contains(t, runner.Env, fmt.Sprintf("SSL_CERT_FILE=%s", caCertsTmpFile)) 243 assertLifecycleCalls(t, runner, 1) 244 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", config.ContainerRegistryURL, config.ContainerImageName, config.ContainerImageTag)) 245 }) 246 247 t.Run("success case (additionalTags)", func(t *testing.T) { 248 t.Parallel() 249 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 250 config := cnbBuildOptions{ 251 ContainerImageName: "my-image", 252 ContainerImageTag: "3.1.5", 253 ContainerRegistryURL: imageRegistry, 254 DockerConfigJSON: "/path/to/config.json", 255 AdditionalTags: []string{"3", "3.1", "3.1", "3.1.5"}, 256 } 257 258 utils := newCnbBuildTestsUtils() 259 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 260 addBuilderFiles(&utils) 261 262 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 263 require.NoError(t, err) 264 265 runner := utils.ExecMockRunner 266 assertLifecycleCalls(t, runner, 1) 267 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:%s", config.ContainerRegistryURL, config.ContainerImageName, config.ContainerImageTag)) 268 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:3", config.ContainerRegistryURL, config.ContainerImageName)) 269 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:3.1", config.ContainerRegistryURL, config.ContainerImageName)) 270 assert.Contains(t, runner.Calls[0].Params, fmt.Sprintf("%s/%s:3.1.5", config.ContainerRegistryURL, config.ContainerImageName)) 271 }) 272 273 t.Run("pom.xml exists (symlink for the target folder)", func(t *testing.T) { 274 t.Parallel() 275 config := cnbBuildOptions{ 276 ContainerImageName: "my-image", 277 ContainerImageTag: "3.1.5", 278 ContainerRegistryURL: imageRegistry, 279 DockerConfigJSON: "/path/to/config.json", 280 } 281 282 utils := newCnbBuildTestsUtils() 283 utils.FilesMock.CurrentDir = "/jenkins" 284 utils.FilesMock.AddDir("/jenkins") 285 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 286 utils.FilesMock.AddFile("/workspace/pom.xml", []byte("test")) 287 addBuilderFiles(&utils) 288 289 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{}) 290 require.NoError(t, err) 291 292 runner := utils.ExecMockRunner 293 assertLifecycleCalls(t, runner, 1) 294 295 assert.True(t, utils.FilesMock.HasCreatedSymlink("/jenkins/target", "/workspace/target")) 296 }) 297 298 t.Run("no pom.xml exists (no symlink for the target folder)", func(t *testing.T) { 299 t.Parallel() 300 config := cnbBuildOptions{ 301 ContainerImageName: "my-image", 302 ContainerImageTag: "3.1.5", 303 ContainerRegistryURL: imageRegistry, 304 DockerConfigJSON: "/path/to/config.json", 305 } 306 307 utils := newCnbBuildTestsUtils() 308 utils.FilesMock.CurrentDir = "/jenkins" 309 utils.FilesMock.AddDir("/jenkins") 310 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 311 addBuilderFiles(&utils) 312 313 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &cnbBuildCommonPipelineEnvironment{}, &piperhttp.Client{}) 314 require.NoError(t, err) 315 316 runner := utils.ExecMockRunner 317 assertLifecycleCalls(t, runner, 1) 318 319 assert.False(t, utils.FilesMock.HasCreatedSymlink("/jenkins/target", "/workspace/target")) 320 }) 321 322 t.Run("error case: Invalid DockerConfigJSON file", func(t *testing.T) { 323 t.Parallel() 324 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 325 config := cnbBuildOptions{ 326 ContainerImageTag: "0.0.1", 327 ContainerRegistryURL: imageRegistry, 328 ContainerImageName: "my-image", 329 DockerConfigJSON: "/path/to/config.json", 330 } 331 332 utils := newCnbBuildTestsUtils() 333 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":"dXNlcjpwYXNz"}}`)) 334 addBuilderFiles(&utils) 335 336 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 337 assert.EqualError(t, err, "failed to generate CNB_REGISTRY_AUTH: json: cannot unmarshal string into Go struct field ConfigFile.auths of type types.AuthConfig") 338 }) 339 340 t.Run("error case: DockerConfigJSON file not there (config.json)", func(t *testing.T) { 341 t.Parallel() 342 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 343 config := cnbBuildOptions{ 344 ContainerImageTag: "0.0.1", 345 ContainerRegistryURL: imageRegistry, 346 ContainerImageName: "my-image", 347 DockerConfigJSON: "not-there/config.json", 348 } 349 350 utils := newCnbBuildTestsUtils() 351 addBuilderFiles(&utils) 352 353 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 354 assert.EqualError(t, err, "failed to generate CNB_REGISTRY_AUTH: could not read 'not-there/config.json'") 355 }) 356 357 t.Run("error case: DockerConfigJSON file not there (not config.json)", func(t *testing.T) { 358 t.Parallel() 359 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 360 config := cnbBuildOptions{ 361 ContainerImageTag: "0.0.1", 362 ContainerRegistryURL: imageRegistry, 363 ContainerImageName: "my-image", 364 DockerConfigJSON: "not-there", 365 } 366 367 utils := newCnbBuildTestsUtils() 368 addBuilderFiles(&utils) 369 370 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 371 assert.EqualError(t, err, "failed to rename DockerConfigJSON file 'not-there': renaming file 'not-there' is not supported, since it does not exist, or is not a leaf-entry") 372 }) 373 374 t.Run("error case: dockerImage is not a valid builder", func(t *testing.T) { 375 t.Parallel() 376 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 377 config := cnbBuildOptions{} 378 379 utils := newCnbBuildTestsUtils() 380 381 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 382 assert.EqualError(t, err, "the provided dockerImage is not a valid builder: binary '/cnb/lifecycle/creator' not found") 383 }) 384 385 t.Run("error case: builder image does not contain tls certificates", func(t *testing.T) { 386 t.Parallel() 387 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 388 config := cnbBuildOptions{ 389 ContainerImageName: "my-image", 390 ContainerImageTag: "0.0.1", 391 ContainerRegistryURL: imageRegistry, 392 DockerConfigJSON: "/path/to/config.json", 393 Buildpacks: []string{"test"}, 394 CustomTLSCertificateLinks: []string{"http://example.com/certs.pem"}, 395 } 396 397 utils := newCnbBuildTestsUtils() 398 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 399 addBuilderFiles(&utils) 400 401 err := callCnbBuild(&config, &telemetry.CustomData{}, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 402 assert.EqualError(t, err, "failed to copy certificates: cannot copy '/etc/ssl/certs/ca-certificates.crt': file does not exist") 403 }) 404 405 t.Run("success case (telemetry was added)", func(t *testing.T) { 406 t.Parallel() 407 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 408 registry := "some-registry" 409 config := cnbBuildOptions{ 410 ContainerImageName: "my-image", 411 ContainerImageTag: "3.1.5", 412 ContainerRegistryURL: registry, 413 DockerConfigJSON: "/path/to/config.json", 414 ProjectDescriptor: "project.toml", 415 AdditionalTags: []string{"latest"}, 416 Buildpacks: []string{"paketobuildpacks/java", "gcr.io/paketo-buildpacks/node"}, 417 Bindings: map[string]interface{}{"SECRET": map[string]string{"key": "KEY", "file": "a_file"}}, 418 Path: "target", 419 } 420 421 utils := newCnbBuildTestsUtils() 422 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 423 utils.FilesMock.AddDir("target") 424 utils.FilesMock.AddFile("target/project.toml", []byte(`[project] 425 id = "test" 426 name = "test" 427 version = "1.0.0" 428 429 [build] 430 include = [] 431 exclude = ["*.tar"] 432 433 [[build.buildpacks]] 434 uri = "some-buildpack"`)) 435 utils.FilesMock.AddFile("a_file", []byte(`{}`)) 436 utils.FilesMock.AddFile("target/somelib.jar", []byte(`FFFFFF`)) 437 438 addBuilderFiles(&utils) 439 440 telemetryData := telemetry.CustomData{} 441 err := callCnbBuild(&config, &telemetryData, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 442 require.NoError(t, err) 443 444 customDataAsString := telemetryData.Custom1 445 customData := cnbBuildTelemetry{} 446 err = json.Unmarshal([]byte(customDataAsString), &customData) 447 448 require.NoError(t, err) 449 assert.Equal(t, 3, customData.Version) 450 require.Equal(t, 1, len(customData.Data)) 451 assert.Equal(t, "3.1.5", customData.Data[0].ImageTag) 452 assert.Equal(t, "folder", string(customData.Data[0].Path)) 453 assert.Contains(t, customData.Data[0].AdditionalTags, "latest") 454 assert.Contains(t, customData.Data[0].BindingKeys, "SECRET") 455 assert.Equal(t, "paketobuildpacks/builder:full", customData.Data[0].Builder) 456 457 assert.Contains(t, customData.Data[0].Buildpacks.FromConfig, "paketobuildpacks/java") 458 assert.NotContains(t, customData.Data[0].Buildpacks.FromProjectDescriptor, "paketobuildpacks/java") 459 assert.Contains(t, customData.Data[0].Buildpacks.FromProjectDescriptor, "<redacted>") 460 assert.NotContains(t, customData.Data[0].Buildpacks.Overall, "<redacted>") 461 assert.Contains(t, customData.Data[0].Buildpacks.Overall, "paketobuildpacks/java") 462 463 assert.True(t, customData.Data[0].ProjectDescriptor.Used) 464 assert.False(t, customData.Data[0].ProjectDescriptor.IncludeUsed) 465 assert.True(t, customData.Data[0].ProjectDescriptor.ExcludeUsed) 466 }) 467 468 t.Run("success case (build env telemetry was added)", func(t *testing.T) { 469 t.Parallel() 470 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 471 registry := "some-registry" 472 config := cnbBuildOptions{ 473 ContainerImageName: "my-image", 474 ContainerImageTag: "3.1.5", 475 ContainerRegistryURL: registry, 476 ProjectDescriptor: "project.toml", 477 BuildEnvVars: map[string]interface{}{"CONFIG_KEY": "var", "BP_JVM_VERSION": "8"}, 478 } 479 480 utils := newCnbBuildTestsUtils() 481 utils.FilesMock.AddFile("project.toml", []byte(`[project] 482 id = "test" 483 484 [build] 485 include = [] 486 487 [[build.env]] 488 name='PROJECT_KEY' 489 value='var' 490 491 [[build.env]] 492 name='BP_NODE_VERSION' 493 value='11' 494 495 [[build.buildpacks]] 496 uri = "some-buildpack" 497 `)) 498 499 addBuilderFiles(&utils) 500 501 telemetryData := telemetry.CustomData{} 502 err := callCnbBuild(&config, &telemetryData, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 503 require.NoError(t, err) 504 505 customDataAsString := telemetryData.Custom1 506 customData := cnbBuildTelemetry{} 507 err = json.Unmarshal([]byte(customDataAsString), &customData) 508 509 require.NoError(t, err) 510 require.Equal(t, 1, len(customData.Data)) 511 assert.Contains(t, customData.Data[0].BuildEnv.KeysFromConfig, "CONFIG_KEY") 512 assert.NotContains(t, customData.Data[0].BuildEnv.KeysFromProjectDescriptor, "CONFIG_KEY") 513 assert.Contains(t, customData.Data[0].BuildEnv.KeysOverall, "CONFIG_KEY") 514 515 assert.NotContains(t, customData.Data[0].BuildEnv.KeysFromConfig, "PROJECT_KEY") 516 assert.Contains(t, customData.Data[0].BuildEnv.KeysFromProjectDescriptor, "PROJECT_KEY") 517 assert.Contains(t, customData.Data[0].BuildEnv.KeysOverall, "PROJECT_KEY") 518 519 assert.Equal(t, "8", customData.Data[0].BuildEnv.KeyValues["BP_JVM_VERSION"]) 520 assert.Equal(t, "11", customData.Data[0].BuildEnv.KeyValues["BP_NODE_VERSION"]) 521 assert.NotContains(t, customData.Data[0].BuildEnv.KeyValues, "PROJECT_KEY") 522 523 assert.Contains(t, customData.Data[0].Buildpacks.Overall, "<redacted>") 524 }) 525 526 t.Run("success case (multiple images configured)", func(t *testing.T) { 527 t.Parallel() 528 commonPipelineEnvironment := cnbBuildCommonPipelineEnvironment{} 529 config := cnbBuildOptions{ 530 ContainerImageTag: "3.1.5", 531 ContainerRegistryURL: imageRegistry, 532 DockerConfigJSON: "/path/to/my-config.json", 533 AdditionalTags: []string{"3", "3.1", "3.1", "3.1.5"}, 534 MultipleImages: []map[string]interface{}{{"ContainerImageName": "my-image-0"}, {"ContainerImageName": "my-image-1"}}, 535 } 536 537 expectedImageCount := len(config.MultipleImages) 538 539 utils := newCnbBuildTestsUtils() 540 utils.FilesMock.AddFile(config.DockerConfigJSON, []byte(`{"auths":{"my-registry":{"auth":"dXNlcjpwYXNz"}}}`)) 541 addBuilderFiles(&utils) 542 543 telemetryData := telemetry.CustomData{} 544 err := callCnbBuild(&config, &telemetryData, &utils, &commonPipelineEnvironment, &piperhttp.Client{}) 545 require.NoError(t, err) 546 547 customDataAsString := telemetryData.Custom1 548 customData := cnbBuildTelemetry{} 549 err = json.Unmarshal([]byte(customDataAsString), &customData) 550 assert.NoError(t, err) 551 require.Equal(t, expectedImageCount, len(customData.Data)) 552 553 runner := utils.ExecMockRunner 554 require.Equal(t, expectedImageCount, len(runner.Calls)) 555 for i, call := range runner.Calls { 556 assert.Equal(t, 4, len(customData.Data[i].AdditionalTags)) 557 assertLifecycleCalls(t, runner, i+1) 558 containerImageName := fmt.Sprintf("my-image-%d", i) 559 assert.Contains(t, call.Params, fmt.Sprintf("%s/%s:%s", config.ContainerRegistryURL, containerImageName, config.ContainerImageTag)) 560 assert.Contains(t, call.Params, fmt.Sprintf("%s/%s:3", config.ContainerRegistryURL, containerImageName)) 561 assert.Contains(t, call.Params, fmt.Sprintf("%s/%s:3.1", config.ContainerRegistryURL, containerImageName)) 562 assert.Contains(t, call.Params, fmt.Sprintf("%s/%s:3.1.5", config.ContainerRegistryURL, containerImageName)) 563 } 564 565 assert.Equal(t, "my-image-0:3.1.5", commonPipelineEnvironment.container.imageNameTag) 566 }) 567 568 }