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  }