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

Adding acceptance tests for nodejs Stack #35

Merged
merged 31 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
9b6c6d0
moving acceptance tests under integration directory
pacostas Dec 18, 2023
44ef9de
creating an integration.json file and adding buildpacks
pacostas Jan 17, 2024
28c1cf0
updating go packages
pacostas Jan 17, 2024
14b07b2
refactoring test.sh script to creating a local registry
pacostas Jan 17, 2024
ad4d495
refactoring metadata acceptance tests
pacostas Jan 17, 2024
9d6d302
feat: adding integration tests to ensure stacks work properly
pacostas Jan 17, 2024
901637b
aligning tools.sh
pacostas Jan 18, 2024
ffd0362
aligning test.sh
pacostas Jan 19, 2024
a517a45
reducing buildpakcs requried for building an app
pacostas Jan 19, 2024
677d38c
adding syft install on tools.sh
pacostas Jan 19, 2024
83bd3b5
removing comments
pacostas Jan 19, 2024
c3a2d5a
refactor: applying review suggestions
pacostas Jan 22, 2024
be961ab
fix: sync create-one with create.sh from github-config repo
pacostas Jan 22, 2024
a391249
adding dependabot.yml file for updating go module dependencies
pacostas Jan 22, 2024
57608c4
refactor: metadata test code reusability
pacostas Jan 23, 2024
dcefc67
adding rest of the buildpacks and using npm to start the app
pacostas Jan 25, 2024
7fb8d4a
renaming the env variable and also a small refactor on the functions
pacostas Jan 30, 2024
9eac669
feat: adding more acceptance tests
pacostas Jan 30, 2024
2b36e05
adding utils file for sharing code among files
pacostas Feb 1, 2024
1a4f6dc
major refactor
pacostas Feb 1, 2024
16bf597
refactor fetching node major varsions on integration.json
pacostas Feb 2, 2024
6cbe1e2
removing sub-buildpacks and adding nodejs buildpack instead
pacostas Feb 2, 2024
46034c2
using stacks structure for code resusability in the future
pacostas Feb 2, 2024
ce7fdf4
a bit of refactory of better code reusability in the future
pacostas Feb 6, 2024
ad96fe1
Moving setting and cleaning local registry to tools.sh file
pacostas Feb 6, 2024
f91fcbf
refactor: moving cleanup in to test.sh in order not to block github c…
pacostas Feb 8, 2024
7616df9
adding java 21 on acceptance tests
pacostas Feb 26, 2024
a895455
fixing issue with overriding build output
pacostas Feb 27, 2024
67f0828
fixing wrong naming
pacostas Feb 27, 2024
9a6b7ac
increasing the time build limit
pacostas Feb 27, 2024
a1fb429
revoving dependabot.yml file as is irrelevant
pacostas Feb 27, 2024
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
16 changes: 13 additions & 3 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ jobs:
search_depth: 1
repo: ${{ github.repository }}
output_path: "/github/workspace/${{ env.UBI_RUN_JAVA_11_SHA256_FILENAME }}"
token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }}
token: ${{ secrets.PAKETO_BOT_GITHUB_TOKEN }}

- name: Find and Download Previous run Java 17 sha256 image hash code
id: fetch_previous_run_java_17_sha256_image_hash_code
Expand Down Expand Up @@ -840,7 +840,7 @@ jobs:
"path": "build-java-17/run.oci.sha256",
"name": ($repo + "-" + $tag + "-" + "run-java-17.oci.sha256"),
"content_type": "application/gzip"
},
},
{
"path": "build-java-21/run.oci",
"name": ($repo + "-" + $tag + "-" + "run-java-21.oci"),
Expand All @@ -850,7 +850,17 @@ jobs:
"path": "build-java-21/run.oci.sha256",
"name": ($repo + "-" + $tag + "-" + "run-java-21.oci.sha256"),
"content_type": "application/gzip"
},
},
{
"path": "build-java-21/run.oci",
"name": ($repo + "-" + $tag + "-" + "run-java-21.oci"),
"content_type": "application/gzip"
},
{
"path": "build-java-21/run.oci.sha256",
"name": ($repo + "-" + $tag + "-" + "run-java-21.oci.sha256"),
"content_type": "application/gzip"
},
{
"path": "build-nodejs-16/run.oci",
"name": ($repo + "-" + $tag + "-" + "run-nodejs-16.oci"),
Expand Down
284 changes: 122 additions & 162 deletions buildpack_integration_test.go
Original file line number Diff line number Diff line change
@@ -1,199 +1,159 @@
package acceptance_test

import (
"bytes"
"encoding/json"
"fmt"
"os"
"path/filepath"
"testing"

"github.com/google/uuid"
structs "github.com/paketo-community/ubi-base-stack/internal/structs"
utils "github.com/paketo-community/ubi-base-stack/internal/utils"
"github.com/sclevine/spec"

. "github.com/onsi/gomega"

"github.com/paketo-buildpacks/occam"
. "github.com/paketo-buildpacks/occam/matchers"
"github.com/paketo-buildpacks/packit/v2/pexec"
)

func testBuildpackIntegration(t *testing.T, context spec.G, it spec.S) {
var (
Expect = NewWithT(t).Expect
Eventually = NewWithT(t).Eventually

buildPlanBuildpack string
goDistBuildpack string
err error

builderConfigFilepath string

pack occam.Pack
docker occam.Docker
source string
name string
builder string
pack occam.Pack
docker occam.Docker
source string
name string

image occam.Image
container occam.Container

buildImageID string
runImageID string
runImageUrl string
builderImageUrl string
)

it.Before(func() {
pack = occam.NewPack().WithVerbose()
docker = occam.NewDocker()

var err error
name, err = occam.RandomName()
Expect(err).NotTo(HaveOccurred())

buildpackStore := occam.NewBuildpackStore()

buildPlanBuildpack, err = buildpackStore.Get.
Execute("github.com/paketo-community/build-plan")
Expect(err).NotTo(HaveOccurred())

goDistBuildpack, err = buildpackStore.Get.
WithVersion("1.2.3").
Execute("github.com/paketo-buildpacks/go-dist")
Expect(err).NotTo(HaveOccurred())

source, err = occam.Source(filepath.Join("integration", "testdata", "simple_app"))
Expect(err).NotTo(HaveOccurred())

builderConfigFile, err := os.CreateTemp("", "builder.toml")
Expect(err).NotTo(HaveOccurred())
builderConfigFilepath = builderConfigFile.Name()

_, err = fmt.Fprintf(builderConfigFile, `
[stack]
build-image = "%s:latest"
id = "io.buildpacks.stacks.ubi8"
run-image = "%s:latest"
`,
stack.BuildImageID,
stack.RunImageID,
)
Expect(err).NotTo(HaveOccurred())

Expect(archiveToDaemon(stack.BuildArchive, stack.BuildImageID)).To(Succeed())
Expect(archiveToDaemon(stack.RunArchive, stack.RunImageID)).To(Succeed())

builder = fmt.Sprintf("builder-%s", uuid.NewString())
logs, err := createBuilder(builderConfigFilepath, builder)
Expect(err).NotTo(HaveOccurred(), logs)
})

it.After(func() {
Expect(docker.Container.Remove.Execute(container.ID)).To(Succeed())
Expect(docker.Image.Remove.Execute(image.ID)).To(Succeed())
Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed())

lifecycleVersion, err := getLifecycleVersion(builder)
Expect(err).NotTo(HaveOccurred())

Expect(docker.Image.Remove.Execute(builder)).To(Succeed())
Expect(os.RemoveAll(builderConfigFilepath)).To(Succeed())

Expect(docker.Image.Remove.Execute(stack.BuildImageID)).To(Succeed())
Expect(docker.Image.Remove.Execute(stack.RunImageID)).To(Succeed())

Expect(docker.Image.Remove.Execute(fmt.Sprintf("buildpacksio/lifecycle:%s", lifecycleVersion))).To(Succeed())

Expect(os.RemoveAll(source)).To(Succeed())
context("When building an app using default stack", func() {

it.After(func() {
Expect(docker.Container.Remove.Execute(container.ID)).To(Succeed())
Expect(docker.Image.Remove.Execute(image.ID)).To(Succeed())
Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed())
err = utils.RemoveImages(docker, []string{buildImageID, runImageID, runImageUrl, builderImageUrl})
Expect(err).NotTo(HaveOccurred())
Expect(os.RemoveAll(source)).To(Succeed())
})

it.Before(func() {
name, err = occam.RandomName()
Expect(err).NotTo(HaveOccurred())

source, err = occam.Source(filepath.Join("integration", "testdata", "simple_app"))
Expect(err).NotTo(HaveOccurred())
})

it("should successfully build a go app", func() {
buildImageID, _, runImageID, runImageUrl, builderImageUrl, err = utils.GenerateBuilder(filepath.Join(root, "build"), RegistryUrl)
Expect(err).NotTo(HaveOccurred())

image, _, err = pack.WithNoColor().Build.
WithBuildpacks(
settings.Buildpacks.GoDist.Online,
settings.Buildpacks.BuildPlan.Online,
).
WithEnv(map[string]string{
"BP_LOG_LEVEL": "DEBUG",
}).
WithPullPolicy("if-not-present").
WithBuilder(builderImageUrl).
Execute(name, source)
Expect(err).NotTo(HaveOccurred())

container, err = docker.Container.Run.
WithDirect().
WithCommand("go").
WithCommandArgs([]string{"run", "main.go"}).
WithEnv(map[string]string{"PORT": "8080"}).
WithPublish("8080").
WithPublishAll().
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())

Eventually(container).Should(BeAvailable())
Eventually(container).Should(Serve(MatchRegexp(`go1.*`)).OnPort(8080))

})
})

it("builds an app with a buildpack", func() {

var err error
var logs fmt.Stringer
image, logs, err = pack.WithNoColor().Build.
WithBuildpacks(
goDistBuildpack,
buildPlanBuildpack,
).
WithEnv(map[string]string{
"BP_LOG_LEVEL": "DEBUG",
}).
WithPullPolicy("if-not-present").
WithBuilder(builder).
Execute(name, source)
Expect(err).ToNot(HaveOccurred(), logs.String)

container, err = docker.Container.Run.
WithDirect().
WithCommand("go").
WithCommandArgs([]string{"run", "main.go"}).
WithEnv(map[string]string{"PORT": "8080"}).
WithPublish("8080").
WithPublishAll().
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())

Eventually(container).Should(BeAvailable())
Eventually(container).Should(Serve(MatchRegexp(`go1.*`)).OnPort(8080))
context("When building an app using nodejs stacks", func() {

it.After(func() {
Expect(docker.Container.Remove.Execute(container.ID)).To(Succeed())
Expect(docker.Image.Remove.Execute(image.ID)).To(Succeed())
Expect(docker.Volume.Remove.Execute(occam.CacheVolumeNames(name))).To(Succeed())
err = utils.RemoveImages(docker, []string{buildImageID, runImageID, runImageUrl, builderImageUrl})
Expect(err).NotTo(HaveOccurred())
Expect(os.RemoveAll(source)).To(Succeed())
})

it.Before(func() {
name, err = occam.RandomName()
Expect(err).NotTo(HaveOccurred())

source, err = occam.Source(filepath.Join("integration", "testdata", "simple_app"))
Expect(err).NotTo(HaveOccurred())
})

var stacks []structs.Stack

for _, nodeMajorVersion := range settings.Config.NodeMajorVersions {
stacks = append(stacks, structs.NewStack(nodeMajorVersion, "nodejs", root))
}

for _, stack := range stacks {
// Create a copy of the stack to get the value and instead of the pointer
stack := stack
it(fmt.Sprintf("it should successfully build a nodejs app with node version %d", stack.MajorVersion), func() {
buildImageID, _, runImageID, runImageUrl, builderImageUrl, err = utils.GenerateBuilder(stack.AbsPath, RegistryUrl)
Expect(err).NotTo(HaveOccurred())

image, _, err = pack.WithNoColor().Build.
WithBuildpacks(
settings.Buildpacks.GoDist.Online,
settings.Buildpacks.BuildPlan.Online,
).
WithEnv(map[string]string{
"BP_LOG_LEVEL": "DEBUG",
}).
WithPullPolicy("if-not-present").
WithBuilder(builderImageUrl).
Execute(name, source)
Expect(err).NotTo(HaveOccurred())

container, err = docker.Container.Run.
WithDirect().
WithCommand("go").
WithCommandArgs([]string{"run", "main.go"}).
WithEnv(map[string]string{"PORT": "8080"}).
WithPublish("8080").
WithPublishAll().
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())

Eventually(container).Should(BeAvailable())
Eventually(container).Should(Serve(MatchRegexp(`go1.*`)).OnPort(8080))
Eventually(container).Should(Serve(MatchRegexp(fmt.Sprintf(`v%d.*`, stack.MajorVersion))).OnPort(8080).WithEndpoint("/node/version"))
})
}
})
}

func archiveToDaemon(path, id string) error {
skopeo := pexec.NewExecutable("skopeo")

return skopeo.Execute(pexec.Execution{
Args: []string{
"copy",
fmt.Sprintf("oci-archive://%s", path),
fmt.Sprintf("docker-daemon:%s:latest", id),
},
})
}

func createBuilder(config string, name string) (string, error) {
buf := bytes.NewBuffer(nil)

pack := pexec.NewExecutable("pack")
err := pack.Execute(pexec.Execution{
Stdout: buf,
Stderr: buf,
Args: []string{
"builder",
"create",
name,
fmt.Sprintf("--config=%s", config),
},
})
return buf.String(), err
}

type Builder struct {
LocalInfo struct {
Lifecycle struct {
Version string `json:"version"`
} `json:"lifecycle"`
} `json:"local_info"`
}

func getLifecycleVersion(builderID string) (string, error) {
buf := bytes.NewBuffer(nil)
pack := pexec.NewExecutable("pack")
err := pack.Execute(pexec.Execution{
Stdout: buf,
Stderr: buf,
Args: []string{
"builder",
"inspect",
builderID,
"-o",
"json",
},
})

if err != nil {
return "", err
}

var builder Builder
err = json.Unmarshal([]byte(buf.String()), &builder)
if err != nil {
return "", err
}
return builder.LocalInfo.Lifecycle.Version, nil
}
Loading
Loading