github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/integration/integration_cnb_test.go (about) 1 //go:build integration 2 // +build integration 3 4 // can be executed with 5 // go test -v -tags integration -run TestCNBIntegration ./integration/... 6 7 package main 8 9 import ( 10 "context" 11 "fmt" 12 "testing" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/testcontainers/testcontainers-go" 16 ) 17 18 const ( 19 registryURL = "localhost:5000" 20 baseBuilder = "paketobuildpacks/builder:0.3.280-base" 21 ) 22 23 func setupDockerRegistry(t *testing.T, ctx context.Context) testcontainers.Container { 24 reqRegistry := testcontainers.ContainerRequest{ 25 Image: "registry:2", 26 SkipReaper: true, 27 } 28 29 regContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ 30 ContainerRequest: reqRegistry, 31 Started: true, 32 }) 33 assert.NoError(t, err) 34 35 return regContainer 36 } 37 38 func TestCNBIntegrationNPMProject(t *testing.T) { 39 t.Parallel() 40 ctx := context.Background() 41 registryContainer := setupDockerRegistry(t, ctx) 42 defer registryContainer.Terminate(ctx) 43 44 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 45 Image: baseBuilder, 46 User: "cnb", 47 TestDir: []string{"testdata", "TestCnbIntegration"}, 48 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 49 Environment: map[string]string{ 50 "PIPER_VAULTCREDENTIAL_DYNATRACE_API_KEY": "api-key-content", 51 }, 52 }) 53 54 container2 := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 55 Image: baseBuilder, 56 User: "cnb", 57 TestDir: []string{"testdata", "TestCnbIntegration"}, 58 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 59 Environment: map[string]string{ 60 "PIPER_VAULTCREDENTIAL_DYNATRACE_API_KEY": "api-key-content", 61 }, 62 }) 63 64 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--path", "project", "--customConfig", "config.yml", "--containerImageName", "node", "--containerImageTag", "0.0.1", "--dockerConfigJSON", "config.json", "--containerRegistryUrl", fmt.Sprintf("http://%s", registryURL), "--defaultProcess", "greeter") 65 assert.NoError(t, err) 66 container.assertHasOutput(t, "running command: /cnb/lifecycle/creator") 67 container.assertHasOutput(t, "Selected Node Engine version (using BP_NODE_VERSION): 16") 68 container.assertHasOutput(t, "Paketo NPM Start Buildpack") 69 container.assertHasOutput(t, fmt.Sprintf("Saving %s/node:0.0.1", registryURL)) 70 container.assertHasOutput(t, "Setting default process type 'greeter'") 71 container.assertHasOutput(t, "*** Images (sha256:") 72 container.assertHasOutput(t, "SUCCESS") 73 container.assertFileContentEquals(t, "/tmp/config.json", "{\n\t\"auths\": {\n\t\t\"test.registry.io\": {},\n\t\t\"test2.registry.io\": {}\n\t}\n}") 74 container.terminate(t) 75 76 err = container2.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--path", "project", "--customConfig", "config.yml", "--containerImageName", "node", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--projectDescriptor", "project-with-id.toml") 77 assert.NoError(t, err) 78 container2.assertHasOutput(t, "running command: /cnb/lifecycle/creator") 79 container2.assertHasOutput(t, "Selected Node Engine version (using BP_NODE_VERSION): 16") 80 container2.assertHasOutput(t, "Paketo NPM Start Buildpack") 81 container2.assertHasOutput(t, fmt.Sprintf("Saving %s/node:0.0.1", registryURL)) 82 container2.assertHasOutput(t, "*** Images (sha256:") 83 container2.assertHasOutput(t, "SUCCESS") 84 container2.assertFileContentEquals(t, "/tmp/config.json", "{\n\t\"auths\": {\n\t\t\"test2.registry.io\": {}\n\t}\n}") 85 container2.terminate(t) 86 } 87 88 func TestCNBIntegrationProjectDescriptor(t *testing.T) { 89 t.Parallel() 90 ctx := context.Background() 91 registryContainer := setupDockerRegistry(t, ctx) 92 defer registryContainer.Terminate(ctx) 93 94 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 95 Image: baseBuilder, 96 User: "cnb", 97 TestDir: []string{"testdata", "TestCnbIntegration", "project"}, 98 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 99 }) 100 101 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL) 102 assert.NoError(t, err) 103 104 container.assertHasOutput(t, "running command: /cnb/lifecycle/creator", 105 "Dockerfile doesn't match include pattern, ignoring", 106 "srv/hello.js matches include pattern", 107 "package.json matches include pattern", 108 "Downloading buildpack", 109 "Setting custom environment variables: 'map[BP_NODE_VERSION:16 TMPDIR:/tmp/cnbBuild-", 110 "Selected Node Engine version (using BP_NODE_VERSION): 16", 111 "Paketo NPM Start Buildpack", 112 fmt.Sprintf("Saving %s/not-found:0.0.1", registryURL), 113 "*** Images (sha256:", 114 "SUCCESS", 115 ) 116 container.terminate(t) 117 } 118 func TestCNBIntegrationBuildSummary(t *testing.T) { 119 t.Parallel() 120 ctx := context.Background() 121 registryContainer := setupDockerRegistry(t, ctx) 122 defer registryContainer.Terminate(ctx) 123 124 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 125 Image: baseBuilder, 126 User: "cnb", 127 TestDir: []string{"testdata", "TestCnbIntegration", "project"}, 128 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 129 }) 130 131 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL) 132 assert.NoError(t, err) 133 134 container.assertHasOutput(t, "*** Build Summary ***", 135 " Builder: \"paketobuildpacks/builder:base\"", 136 " Lifecycle: \"0.16.4+683e1b46\"", 137 " Image: \"localhost:5000/not-found@sha256:", 138 " Project descriptor: \"/project/project.toml\"", 139 " Env: \"TMPDIR, BP_NODE_VERSION\"") 140 container.terminate(t) 141 } 142 143 func TestCNBIntegrationZipPath(t *testing.T) { 144 t.Parallel() 145 ctx := context.Background() 146 registryContainer := setupDockerRegistry(t, ctx) 147 defer registryContainer.Terminate(ctx) 148 149 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 150 Image: baseBuilder, 151 User: "cnb", 152 TestDir: []string{"testdata", "TestCnbIntegration", "zip"}, 153 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 154 }) 155 156 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--path", "go.zip", "--createBOM") 157 assert.NoError(t, err) 158 159 container.assertHasOutput(t, 160 "running command: /cnb/lifecycle/creator", 161 "Installing Go", 162 "Paketo Buildpack for Go Build", 163 fmt.Sprintf("Saving %s/not-found:0.0.1", registryURL), 164 "*** Images (sha256:", 165 "SUCCESS", 166 "syft packages registry:localhost:5000/not-found:0.0.1 -o cyclonedx-xml --file bom-docker-0.xml -q", 167 ) 168 container.assertHasFiles(t, "/project/bom-docker-0.xml") 169 container.terminate(t) 170 } 171 172 func TestCNBIntegrationNonZipPath(t *testing.T) { 173 t.Parallel() 174 ctx := context.Background() 175 registryContainer := setupDockerRegistry(t, ctx) 176 defer registryContainer.Terminate(ctx) 177 178 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 179 Image: baseBuilder, 180 User: "cnb", 181 TestDir: []string{"testdata", "TestMtaIntegration", "npm"}, 182 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 183 }) 184 185 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--path", "mta.yaml") 186 assert.Error(t, err) 187 188 container.assertHasOutput(t, "Copying '/project/mta.yaml' into '/workspace' failed: application path must be a directory or zip") 189 container.terminate(t) 190 } 191 192 func TestCNBIntegrationNPMCustomBuildpacksFullProject(t *testing.T) { 193 t.Parallel() 194 ctx := context.Background() 195 registryContainer := setupDockerRegistry(t, ctx) 196 defer registryContainer.Terminate(ctx) 197 198 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 199 Image: baseBuilder, 200 User: "cnb", 201 TestDir: []string{"testdata", "TestMtaIntegration", "npm"}, 202 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 203 }) 204 205 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--buildpacks", "gcr.io/paketo-buildpacks/nodejs:0.19.0", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL) 206 assert.NoError(t, err) 207 208 container.assertHasOutput(t, 209 "Setting custom buildpacks: '[gcr.io/paketo-buildpacks/nodejs:0.19.0]'", 210 "Downloading buildpack 'gcr.io/paketo-buildpacks/nodejs:0.19.0' to /tmp/buildpacks_cache/sha256:", 211 "running command: /cnb/lifecycle/creator", 212 "Paketo NPM Start Buildpack", 213 fmt.Sprintf("Saving %s/not-found:0.0.1", registryURL), 214 "*** Images (sha256:", 215 "SUCCESS", 216 ) 217 container.terminate(t) 218 } 219 220 func TestCNBIntegrationNPMCustomBuildpacksBuildpacklessProject(t *testing.T) { 221 t.Parallel() 222 ctx := context.Background() 223 registryContainer := setupDockerRegistry(t, ctx) 224 defer registryContainer.Terminate(ctx) 225 226 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 227 Image: "paketobuildpacks/builder:buildpackless-full", 228 User: "cnb", 229 TestDir: []string{"testdata", "TestMtaIntegration", "npm"}, 230 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 231 }) 232 233 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--buildpacks", "gcr.io/paketo-buildpacks/nodejs:0.19.0", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL) 234 assert.NoError(t, err) 235 236 container.assertHasOutput(t, "Setting custom buildpacks: '[gcr.io/paketo-buildpacks/nodejs:0.19.0]'", 237 "Downloading buildpack 'gcr.io/paketo-buildpacks/nodejs:0.19.0' to /tmp/buildpacks_cache/sha256:", 238 "running command: /cnb/lifecycle/creator", 239 "Paketo NPM Start Buildpack", 240 fmt.Sprintf("Saving %s/not-found:0.0.1", registryURL), 241 "*** Images (sha256:", 242 "SUCCESS", 243 ) 244 container.terminate(t) 245 } 246 247 func TestCNBIntegrationWrongBuilderProject(t *testing.T) { 248 t.Parallel() 249 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 250 Image: "nginx:latest", 251 TestDir: []string{"testdata", "TestMtaIntegration", "npm"}, 252 }) 253 254 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", "test") 255 assert.Error(t, err) 256 257 container.assertHasOutput(t, "the provided dockerImage is not a valid builder") 258 container.terminate(t) 259 } 260 261 func TestCNBIntegrationBindings(t *testing.T) { 262 t.Parallel() 263 ctx := context.Background() 264 registryContainer := setupDockerRegistry(t, ctx) 265 defer registryContainer.Terminate(ctx) 266 267 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 268 Image: baseBuilder, 269 User: "cnb", 270 TestDir: []string{"testdata", "TestCnbIntegration"}, 271 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 272 Environment: map[string]string{ 273 "PIPER_VAULTCREDENTIAL_DYNATRACE_API_KEY": "api-key-content", 274 }, 275 }) 276 277 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "config.yml", "--containerImageName", "not-found", "--containerImageTag", "0.0.1", "--containerRegistryUrl", registryURL, "--path", "project") 278 assert.NoError(t, err) 279 280 container.assertHasFiles(t, 281 "/tmp/platform/bindings/dummy-binding/type", 282 "/tmp/platform/bindings/dummy-binding/dummy.yml", 283 ) 284 container.assertFileContentEquals(t, "/tmp/platform/bindings/maven-settings/settings.xml", "invalid xml") 285 container.assertFileContentEquals(t, "/tmp/platform/bindings/dynatrace/api-key", "api-key-content") 286 container.terminate(t) 287 } 288 289 func TestCNBIntegrationMultiImage(t *testing.T) { 290 t.Parallel() 291 ctx := context.Background() 292 registryContainer := setupDockerRegistry(t, ctx) 293 defer registryContainer.Terminate(ctx) 294 295 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 296 Image: baseBuilder, 297 User: "cnb", 298 TestDir: []string{"testdata", "TestCnbIntegration"}, 299 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 300 }) 301 302 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "config_multi_image.yml", "--createBOM") 303 assert.NoError(t, err) 304 305 container.assertHasOutput(t, 306 "Image with name \"localhost:5000/io-buildpacks-my-app:latest\" not found", 307 "Saving localhost:5000/io-buildpacks-my-app:latest...", 308 "Image with name \"localhost:5000/go-app:v1.0.0\" not found", 309 "Saving localhost:5000/go-app:v1.0.0...", 310 "Using cached buildpack", 311 "Saving localhost:5000/my-app2:latest...", 312 "syft packages registry:localhost:5000/io-buildpacks-my-app:latest -o cyclonedx-xml --file bom-docker-0.xml -q", 313 "syft packages registry:localhost:5000/go-app:v1.0.0 -o cyclonedx-xml --file bom-docker-1.xml -q", 314 "syft packages registry:localhost:5000/my-app2:latest -o cyclonedx-xml --file bom-docker-2.xml -q", 315 ) 316 317 container.assertHasFiles(t, "/project/bom-docker-0.xml") 318 container.assertHasFiles(t, "/project/bom-docker-1.xml") 319 container.assertHasFiles(t, "/project/bom-docker-2.xml") 320 container.terminate(t) 321 } 322 323 func TestCNBIntegrationPreserveFiles(t *testing.T) { 324 t.Parallel() 325 ctx := context.Background() 326 registryContainer := setupDockerRegistry(t, ctx) 327 defer registryContainer.Terminate(ctx) 328 329 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 330 Image: baseBuilder, 331 User: "cnb", 332 TestDir: []string{"testdata", "TestCnbIntegration"}, 333 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 334 }) 335 336 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "config_preserve_files.yml") 337 assert.NoError(t, err) 338 339 container.assertHasFiles(t, "/project/project/node_modules/base/README.md", "/project/project/package-lock.json") 340 container.terminate(t) 341 } 342 343 func TestCNBIntegrationPreserveFilesIgnored(t *testing.T) { 344 t.Parallel() 345 ctx := context.Background() 346 registryContainer := setupDockerRegistry(t, ctx) 347 defer registryContainer.Terminate(ctx) 348 349 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 350 Image: baseBuilder, 351 User: "cnb", 352 TestDir: []string{"testdata", "TestCnbIntegration"}, 353 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 354 }) 355 356 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--customConfig", "config_preserve_files.yml", "--path", "zip/go.zip", "--containerImageName", "go-zip") 357 assert.NoError(t, err) 358 container.assertHasOutput(t, "skipping preserving files because the source") 359 container.terminate(t) 360 } 361 362 func TestCNBIntegrationPrePostBuildpacks(t *testing.T) { 363 t.Parallel() 364 ctx := context.Background() 365 registryContainer := setupDockerRegistry(t, ctx) 366 defer registryContainer.Terminate(ctx) 367 368 container := givenThisContainer(t, IntegrationTestDockerExecRunnerBundle{ 369 Image: baseBuilder, 370 User: "cnb", 371 TestDir: []string{"testdata", "TestCnbIntegration"}, 372 Network: fmt.Sprintf("container:%s", registryContainer.GetContainerID()), 373 Environment: map[string]string{ 374 "PIPER_VAULTCREDENTIAL_DYNATRACE_API_KEY": "api-key-content", 375 }, 376 }) 377 378 err := container.whenRunningPiperCommand("cnbBuild", "--noTelemetry", "--verbose", "--projectDescriptor", "", "--path", "project", "--customConfig", "config.yml", "--containerImageTag", "0.0.1", "--containerImageName", "not-found", "--containerRegistryUrl", registryURL, "--postBuildpacks", "paketobuildpacks/datadog") 379 assert.NoError(t, err) 380 container.assertHasOutput(t, "Setting custom buildpacks: '[]'") 381 container.assertHasOutput(t, "Pre-buildpacks: '[]'") 382 container.assertHasOutput(t, "Post-buildpacks: '[paketobuildpacks/datadog]'") 383 container.terminate(t) 384 }