Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add acceptance tests for cnb lifecycle #1136

Merged
merged 3 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ Test Group Name| Description
`app_syslog_tcp`| Tests the ability to configure an app syslog drain listener.
`apps`| Tests the core functionalities of Cloud Foundry: staging, running, logging, routing, buildpacks, etc. This test group should always pass against a sound Cloud Foundry deployment.
`credhub`| Tests CredHub-delivered Secure Service credentials in the service binding. [CredHub configuration][credhub-secure-service-credentials] is required to run these tests. In addition to selecting a `credhub_mode`, `credhub_client` and `credhub_secret` values are required for these tests.
`cnb` | Tests our ability to use cloud native buildpacks.
`detect` | Tests the ability of the platform to detect the correct buildpack for compiling an application if no buildpack is explicitly specified.
`docker`| Tests our ability to run docker containers on Diego and that we handle docker metadata correctly.
`internet_dependent`| Tests the feature of being able to specify a buildpack via a Github URL. As such, this depends on your Cloud Foundry application containers having access to the Internet. You should take into account the configuration of the network into which you've deployed your Cloud Foundry, as well as any security group settings applied to application containers.
Expand Down
3 changes: 3 additions & 0 deletions assets/cnb-node/manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
applications:
- lifecycle: cnb
4 changes: 4 additions & 0 deletions assets/cnb-node/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name" : "node_without_procfile",
"version": "0.1.0"
}
16 changes: 16 additions & 0 deletions assets/cnb-node/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
var http = require('http');
var url = require('url');

HOST = null;

var host = "0.0.0.0";
var port = process.env.PORT || 3000;

http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Hello from a node app! ');
res.write('via: ' + host + ':' + port);
res.end('</h1>');
}).listen(port, null);

console.log('Server running at http://' + host + ':' + port + '/');
11 changes: 11 additions & 0 deletions cats_suite_helpers/cats_suite_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ func DockerDescribe(description string, callback func()) bool {
})
}

func CNBDescribe(description string, callback func()) bool {
return Describe("[cnb]", func() {
BeforeEach(func() {
if !Config.GetIncludeCNB() {
Skip(skip_messages.SkipCNBMessage)
}
})
Describe(description, callback)
})
}

func InternetDependentDescribe(description string, callback func()) bool {
return Describe("[internet_dependent]", func() {
BeforeEach(func() {
Expand Down
1 change: 1 addition & 0 deletions cats_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

_ "github.com/cloudfoundry/cf-acceptance-tests/app_syslog_tcp"
_ "github.com/cloudfoundry/cf-acceptance-tests/apps"
_ "github.com/cloudfoundry/cf-acceptance-tests/cnb"
_ "github.com/cloudfoundry/cf-acceptance-tests/credhub"
_ "github.com/cloudfoundry/cf-acceptance-tests/detect"
_ "github.com/cloudfoundry/cf-acceptance-tests/docker"
Expand Down
67 changes: 67 additions & 0 deletions cnb/cnb_lifecycle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//go:build !noInternet && !noCNB
// +build !noInternet,!noCNB
ctlong marked this conversation as resolved.
Show resolved Hide resolved

package cnb

import (
"path/filepath"

. "github.com/cloudfoundry/cf-acceptance-tests/cats_suite_helpers"
"github.com/cloudfoundry/cf-acceptance-tests/helpers/app_helpers"
"github.com/cloudfoundry/cf-acceptance-tests/helpers/assets"
"github.com/cloudfoundry/cf-acceptance-tests/helpers/random_name"
"github.com/cloudfoundry/cf-test-helpers/v2/cf"
"github.com/cloudfoundry/cf-test-helpers/v2/helpers"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gbytes"
. "github.com/onsi/gomega/gexec"
)

var _ = CNBDescribe("CloudNativeBuildpacks lifecycle", func() {
var appName string

BeforeEach(func() {
appName = random_name.CATSRandomName("CNB-APP")
})

AfterEach(func() {
app_helpers.AppReport(appName)
Eventually(cf.Cf("delete", appName, "-f")).Should(Exit(0))
})

Describe("pushing Node.js application with Cloud Native Buildpacks", func() {
It("makes the app reachable via its bound route", func() {
Expect(cf.Cf("push",
appName,
"-p", assets.NewAssets().CNBNode,
"-b", Config.GetCNBNodejsBuildpackName(),
"-f", filepath.Join(assets.NewAssets().CNBNode, "manifest.yml"),
).Wait(Config.CfPushTimeoutDuration())).To(Exit(0))

Eventually(func() string {
return helpers.CurlAppRoot(Config, appName)
}).Should(ContainSubstring("Hello from a node app!"))
})
})

Describe("pushing Node.js application with CNB lifecycle and no buildpacks", func() {
It("fails", func() {
push := cf.Cf("push",
appName,
"-p", assets.NewAssets().CNBNode,
"-f", filepath.Join(assets.NewAssets().CNBNode, "manifest.yml"),
).Wait(Config.CfPushTimeoutDuration())

Expect(push).To(Exit(1))
Expect(combineOutput(push.Out, push.Err)).To(Say("Buildpack\\(s\\) must be specified when using Cloud Native Buildpacks"))
})
})
})

func combineOutput(outBuffer *Buffer, errBuffer *Buffer) *Buffer {
combinedOutput := BufferWithBytes(outBuffer.Contents())
combinedOutput.Write(errBuffer.Contents())
return combinedOutput
}
2 changes: 2 additions & 0 deletions helpers/assets/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Assets struct {
Python string
Nginx string
Node string
CNBNode string
NodeWithProcfile string
Nora string
Pora string
Expand Down Expand Up @@ -67,6 +68,7 @@ func NewAssets() Assets {
LoggregatorLoadGeneratorGo: "assets/loggregator-load-generator-go",
Nginx: "assets/nginx",
Node: "assets/node",
CNBNode: "assets/cnb-node",
NodeWithProcfile: "assets/node-with-procfile",
Nora: "assets/nora/NoraPublished",
Pora: "assets/pora",
Expand Down
2 changes: 2 additions & 0 deletions helpers/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type CatsConfig interface {
GetIncludeCredhubNonAssisted() bool
GetIncludeDetect() bool
GetIncludeDocker() bool
GetIncludeCNB() bool
GetIncludeInternetDependent() bool
GetIncludePrivateDockerRegistry() bool
GetIncludeRouteServices() bool
Expand Down Expand Up @@ -70,6 +71,7 @@ type CatsConfig interface {
GetNamePrefix() string
GetNginxBuildpackName() string
GetNodejsBuildpackName() string
GetCNBNodejsBuildpackName() string
GetPrivateDockerRegistryImage() string
GetPrivateDockerRegistryUsername() string
GetPrivateDockerRegistryPassword() string
Expand Down
20 changes: 20 additions & 0 deletions helpers/config/config_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ type config struct {
RubyBuildpackName *string `json:"ruby_buildpack_name"`
StaticFileBuildpackName *string `json:"staticfile_buildpack_name"`

CNBNodejsBuildpackName *string `json:"cnb_nodejs_buildpack_name"`
ctlong marked this conversation as resolved.
Show resolved Hide resolved

VolumeServiceName *string `json:"volume_service_name"`
VolumeServicePlanName *string `json:"volume_service_plan_name"`
VolumeServiceCreateConfig *string `json:"volume_service_create_config"`
Expand All @@ -71,6 +73,7 @@ type config struct {
IncludeDeployments *bool `json:"include_deployments"`
IncludeDetect *bool `json:"include_detect"`
IncludeDocker *bool `json:"include_docker"`
IncludeCNB *bool `json:"include_cnb"`
ctlong marked this conversation as resolved.
Show resolved Hide resolved
IncludeInternetDependent *bool `json:"include_internet_dependent"`
IncludeIsolationSegments *bool `json:"include_isolation_segments"`
IncludePrivateDockerRegistry *bool `json:"include_private_docker_registry"`
Expand Down Expand Up @@ -157,6 +160,8 @@ func getDefaults() config {
defaults.RubyBuildpackName = ptrToString("ruby_buildpack")
defaults.StaticFileBuildpackName = ptrToString("staticfile_buildpack")

defaults.CNBNodejsBuildpackName = ptrToString("docker://gcr.io/paketo-buildpacks/nodejs:latest")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this cause test flakiness when there are network issues?


defaults.IncludeAppSyslogTCP = ptrToBool(true)
defaults.IncludeApps = ptrToBool(true)
defaults.IncludeDetect = ptrToBool(true)
Expand All @@ -170,6 +175,7 @@ func getDefaults() config {
defaults.CredhubClientName = ptrToString("credhub_admin_client")
defaults.CredhubClientSecret = ptrToString("")
defaults.IncludeDocker = ptrToBool(false)
defaults.IncludeCNB = ptrToBool(false)
defaults.IncludeInternetDependent = ptrToBool(false)
defaults.IncludeIsolationSegments = ptrToBool(false)
defaults.IncludeTCPIsolationSegments = ptrToBool(false)
Expand Down Expand Up @@ -400,6 +406,9 @@ func validateConfig(config *config) error {
if config.StaticFileBuildpackName == nil {
errs = errors.Join(errs, fmt.Errorf("* 'staticfile_buildpack_name' must not be null"))
}
if config.CNBNodejsBuildpackName == nil {
errs = errors.Join(errs, fmt.Errorf("* 'cnb_nodejs_buildpack_name' must not be null"))
}
if config.IncludeAppSyslogTCP == nil {
errs = errors.Join(errs, fmt.Errorf("* 'include_app_syslog_tcp' must not be null"))
}
Expand All @@ -415,6 +424,9 @@ func validateConfig(config *config) error {
if config.IncludeDocker == nil {
errs = errors.Join(errs, fmt.Errorf("* 'include_docker' must not be null"))
}
if config.IncludeCNB == nil {
errs = errors.Join(errs, fmt.Errorf("* 'include_cnb' must not be null"))
}
if config.IncludeInternetDependent == nil {
errs = errors.Join(errs, fmt.Errorf("* 'include_internet_dependent' must not be null"))
}
Expand Down Expand Up @@ -901,6 +913,10 @@ func (c *config) GetIncludeDocker() bool {
return *c.IncludeDocker
}

func (c *config) GetIncludeCNB() bool {
return *c.IncludeCNB
}

func (c *config) GetIncludeInternetDependent() bool {
return *c.IncludeInternetDependent
}
Expand Down Expand Up @@ -1049,6 +1065,10 @@ func (c *config) GetStaticFileBuildpackName() string {
return *c.StaticFileBuildpackName
}

func (c *config) GetCNBNodejsBuildpackName() string {
return *c.CNBNodejsBuildpackName
}

func (c *config) GetPrivateDockerRegistryImage() string {
return *c.PrivateDockerRegistryImage
}
Expand Down
2 changes: 2 additions & 0 deletions helpers/skip_messages/skip_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const SkipContainerNetworkingMessage = `Skipping this test because config.Includ
const SkipDetectMessage = `Skipping this test because config.IncludeDetect is set to 'false'.`
const SkipDockerMessage = `Skipping this test because config.IncludeDocker is set to 'false'.
NOTE: Ensure Docker containers are enabled on your platform before enabling this test.`
const SkipCNBMessage = `Skipping this test because config.IncludeCNB is set to 'false'.
NOTE: Ensure CNB lifecycle is enabled on your platform before enabling this test.`
const SkipInternetDependentMessage = `Skipping this test because config.IncludeInternetDependent is set to 'false'.
NOTE: Ensure that your platform has access to the internet before running this test.`
const SkipPrivateDockerRegistryMessage = `Skipping this test because config.IncludePrivateDockerRegistry is set to 'false'.
Expand Down