From f21d3f49611c2267f267dfb380b370dea2105e51 Mon Sep 17 00:00:00 2001 From: Costas Papastathis Date: Wed, 14 Aug 2024 11:51:45 +0300 Subject: [PATCH 1/2] refactor: metadata fetching build image according to createBuildImage flag --- init_test.go | 34 +++++++++++- metadata_test.go | 139 ++++++++++++++++++----------------------------- 2 files changed, 85 insertions(+), 88 deletions(-) diff --git a/init_test.go b/init_test.go index cb02b09..dc4640e 100644 --- a/init_test.go +++ b/init_test.go @@ -19,6 +19,27 @@ import ( var root string var RegistryUrl string +type StackImages struct { + Name string `json:"name"` + ConfigDir string `json:"config_dir"` + OutputDir string `json:"output_dir"` + BuildImage string `json:"build_image"` + RunImage string `json:"run_image"` + BuildReceiptFilename string `json:"build_receipt_filename"` + RunReceiptFilename string `json:"run_receipt_filename"` + CreateBuildImage bool `json:"create_build_image,omitempty"` + BaseBuildContainerImage string `json:"base_build_container_image,omitempty"` + BaseRunContainerImage string `json:"base_run_container_image"` + Type string `json:"type,omitempty"` +} + +type ImagesJson struct { + SupportUsns bool `json:"support_usns"` + UpdateOnNewImage bool `json:"update_on_new_image"` + ReceiptsShowLimit int `json:"receipts_show_limit"` + Images []StackImages `json:"images"` +} + var builder struct { imageUrl string buildImageUrl string @@ -53,6 +74,7 @@ var settings struct { } Stacks []structs.Stack + ImagesJson ImagesJson } func by(_ string, f func()) { f() } @@ -74,11 +96,17 @@ func TestAcceptance(t *testing.T) { root, err = filepath.Abs(".") Expect(err).ToNot(HaveOccurred()) - file, err := os.Open("./integration.json") + integration_json, err := os.Open("./integration.json") + Expect(err).NotTo(HaveOccurred()) + + Expect(json.NewDecoder(integration_json).Decode(&settings.Config)).To(Succeed()) + Expect(integration_json.Close()).To(Succeed()) + + images_json, err := os.Open("./images.json") Expect(err).NotTo(HaveOccurred()) - Expect(json.NewDecoder(file).Decode(&settings.Config)).To(Succeed()) - Expect(file.Close()).To(Succeed()) + Expect(json.NewDecoder(images_json).Decode(&settings.ImagesJson)).To(Succeed()) + Expect(images_json.Close()).To(Succeed()) buildpackStore := occam.NewBuildpackStore() diff --git a/metadata_test.go b/metadata_test.go index 54e2f5f..eef4503 100644 --- a/metadata_test.go +++ b/metadata_test.go @@ -1,9 +1,7 @@ package acceptance_test import ( - "encoding/json" "fmt" - "io" "os" "path/filepath" "testing" @@ -19,44 +17,8 @@ import ( . "github.com/paketo-buildpacks/occam/matchers" ) -type Images struct { - SupportUsns bool `json:"support_usns"` - UpdateOnNewImage bool `json:"update_on_new_image"` - receiptsShowLimit int `json:"receipts_show_limit"` - Images []Image `json:"images"` -} - -type Image struct { - Name string `json:"name"` - configDir string `json:"config_dir"` - OutputDir string `json:"output_dir"` - BuildImage string `json:"build_image"` - RunImage string `json:"run_image"` - BuildReceiptFilename string `json:"build_receipt_filename"` - RunReceiptFilename string `json:"run_receipt_filename"` - CreateBuildImage bool `json:"create_build_image"` - BaseBuildContainerImage string `json:"base_build_container_image"` - BaseRunContainerImage string `json:"base_run_container_image"` -} - func testMetadata(t *testing.T, context spec.G, it spec.S) { - jsonFile, err := os.Open("images.json") - if err != nil { - fmt.Println(err) - } - - defer jsonFile.Close() - - byteValue, _ := io.ReadAll(jsonFile) - - var images Images - - err = json.Unmarshal(byteValue, &images) - if err != nil { - fmt.Println(err) - } - var ( Expect = NewWithT(t).Expect @@ -79,55 +41,62 @@ func testMetadata(t *testing.T, context spec.G, it spec.S) { runReleaseDate time.Time ) - by("confirming that the build image is correct", func() { - index, manifests, err := getImageIndexAndManifests(tmpDir, filepath.Join(root, "./build", "build.oci")) - Expect(err).NotTo(HaveOccurred()) - - Expect(manifests).To(HaveLen(1)) - Expect(manifests[0].Platform).To(Equal(&v1.Platform{ - OS: "linux", - Architecture: "amd64", - })) - - image, err := index.Image(manifests[0].Digest) - Expect(err).NotTo(HaveOccurred()) - - file, err := image.ConfigFile() - Expect(err).NotTo(HaveOccurred()) - - Expect(file.Config.Labels).To(SatisfyAll( - HaveKeyWithValue("io.buildpacks.stack.id", "io.buildpacks.stacks.ubi8"), - HaveKeyWithValue("io.buildpacks.stack.description", "base build ubi8 image to support buildpacks"), - HaveKeyWithValue("io.buildpacks.stack.distro.name", "rhel"), - HaveKeyWithValue("io.buildpacks.stack.distro.version", MatchRegexp(`8\.\d+`)), - HaveKeyWithValue("io.buildpacks.stack.homepage", "https://github.com/paketo-community/ubi-base-stack"), - HaveKeyWithValue("io.buildpacks.stack.maintainer", "Paketo Community"), - HaveKeyWithValue("io.buildpacks.stack.metadata", MatchJSON("{}")), - )) - - buildReleaseDate, err = time.Parse(time.RFC3339, file.Config.Labels["io.buildpacks.stack.released"]) - Expect(err).NotTo(HaveOccurred()) - Expect(buildReleaseDate).NotTo(BeZero()) - - Expect(image).To(SatisfyAll( - HaveFileWithContent("/etc/group", ContainSubstring("cnb:x:1000:")), - HaveFileWithContent("/etc/passwd", ContainSubstring("cnb:x:1002:1000::/home/cnb:/bin/bash")), - HaveDirectory("/home/cnb"), - )) - - Expect(file.Config.User).To(Equal("1002:1000")) - - Expect(file.Config.Env).To(ContainElements( - "CNB_USER_ID=1002", - "CNB_GROUP_ID=1000", - "CNB_STACK_ID=io.buildpacks.stacks.ubi8", - )) - }) - - for _, imageInfo := range images.Images { + for _, imageInfo := range settings.ImagesJson.StackImages { + + if !imageInfo.CreateBuildImage { + continue + } + + by("confirming that the build image is correct", func() { + index, manifests, err := getImageIndexAndManifests(tmpDir, filepath.Join(root, imageInfo.OutputDir, "build.oci")) + Expect(err).NotTo(HaveOccurred()) + + Expect(manifests).To(HaveLen(1)) + Expect(manifests[0].Platform).To(Equal(&v1.Platform{ + OS: "linux", + Architecture: "amd64", + })) + + image, err := index.Image(manifests[0].Digest) + Expect(err).NotTo(HaveOccurred()) + + file, err := image.ConfigFile() + Expect(err).NotTo(HaveOccurred()) + + Expect(file.Config.Labels).To(SatisfyAll( + HaveKeyWithValue("io.buildpacks.stack.id", "io.buildpacks.stacks.ubi8"), + HaveKeyWithValue("io.buildpacks.stack.description", "base build ubi8 image to support buildpacks"), + HaveKeyWithValue("io.buildpacks.stack.distro.name", "rhel"), + HaveKeyWithValue("io.buildpacks.stack.distro.version", MatchRegexp(`8\.\d+`)), + HaveKeyWithValue("io.buildpacks.stack.homepage", "https://github.com/paketo-community/ubi-base-stack"), + HaveKeyWithValue("io.buildpacks.stack.maintainer", "Paketo Community"), + HaveKeyWithValue("io.buildpacks.stack.metadata", MatchJSON("{}")), + )) + + buildReleaseDate, err = time.Parse(time.RFC3339, file.Config.Labels["io.buildpacks.stack.released"]) + Expect(err).NotTo(HaveOccurred()) + Expect(buildReleaseDate).NotTo(BeZero()) + + Expect(image).To(SatisfyAll( + HaveFileWithContent("/etc/group", ContainSubstring("cnb:x:1000:")), + HaveFileWithContent("/etc/passwd", ContainSubstring("cnb:x:1002:1000::/home/cnb:/bin/bash")), + HaveDirectory("/home/cnb"), + )) + + Expect(file.Config.User).To(Equal("1002:1000")) + + Expect(file.Config.Env).To(ContainElements( + "CNB_USER_ID=1002", + "CNB_GROUP_ID=1000", + "CNB_STACK_ID=io.buildpacks.stacks.ubi8", + )) + }) + } + + for _, imageInfo := range settings.ImagesJson.StackImages { by(fmt.Sprintf("confirming that the run %s image is correct", imageInfo.Name), func() { - index, manifests, err := getImageIndexAndManifests(tmpDir, filepath.Join(root, fmt.Sprintf("./%s", imageInfo.OutputDir), "run.oci")) + index, manifests, err := getImageIndexAndManifests(tmpDir, filepath.Join(root, imageInfo.OutputDir, "run.oci")) Expect(err).NotTo(HaveOccurred()) Expect(manifests).To(HaveLen(1)) From db954270be33e0909dc0ff86da7df5b086a94946 Mon Sep 17 00:00:00 2001 From: Costas Papastathis Date: Wed, 14 Aug 2024 19:05:57 +0300 Subject: [PATCH 2/2] conditionaly testing any stack --- buildpack_integration_test.go | 82 +++++++++++++++++++------------- init_test.go | 29 +++++++---- integration.json | 3 -- nodejs_stack_integration_test.go | 26 +++++----- 4 files changed, 83 insertions(+), 57 deletions(-) diff --git a/buildpack_integration_test.go b/buildpack_integration_test.go index 59efe6c..7399ecc 100644 --- a/buildpack_integration_test.go +++ b/buildpack_integration_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "regexp" "testing" utils "github.com/paketo-community/ubi-base-stack/internal/utils" @@ -58,37 +59,45 @@ func testBuildpackIntegration(t *testing.T, context spec.G, it spec.S) { Expect(err).NotTo(HaveOccurred()) }) - it("should successfully build a go app", func() { - _, runImageUrl, builderImageUrl, err = utils.GenerateBuilder(root, "build", RegistryUrl) - Expect(err).NotTo(HaveOccurred()) + for _, stack := range settings.ImagesJson.StackImages { + stack := stack - 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()) + if stack.Name != "default" { + continue + } - 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()) + it("should successfully build a go app", func() { + _, runImageUrl, builderImageUrl, err = utils.GenerateBuilder(root, "build", RegistryUrl) + Expect(err).NotTo(HaveOccurred()) - Eventually(container).Should(BeAvailable()) - Eventually(container).Should(Serve(MatchRegexp(`go1.*`)).OnPort(8080)) + 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)) + + }) + } }) context("When building an app using Node.js stacks", func() { @@ -110,11 +119,18 @@ func testBuildpackIntegration(t *testing.T, context spec.G, it spec.S) { Expect(err).NotTo(HaveOccurred()) }) - for _, stack := range settings.Stacks { + nodejsRegex, _ := regexp.Compile("^nodejs") + + for _, stack := range settings.ImagesJson.StackImages { // Create a copy of the stack to get the value instead of a pointer stack := stack - it(fmt.Sprintf("it should successfully build a nodejs app with node version %d", stack.MajorVersion), func() { - _, runImageUrl, builderImageUrl, err = utils.GenerateBuilder(root, stack.Path, RegistryUrl) + + if !nodejsRegex.MatchString(stack.Name) { + continue + } + + it(fmt.Sprintf("it should successfully get the %s version of the run image", stack.Name), func() { + _, runImageUrl, builderImageUrl, err = utils.GenerateBuilder(root, stack.OutputDir, RegistryUrl) Expect(err).NotTo(HaveOccurred()) image, _, err = pack.WithNoColor().Build. @@ -142,11 +158,9 @@ func testBuildpackIntegration(t *testing.T, context spec.G, it spec.S) { Eventually(container).Should(BeAvailable()) Eventually(container).Should(Serve(MatchRegexp(`go1.*`)).OnPort(8080)) - - engineVersionEndpoint := fmt.Sprintf("/nodejs/v%d/version", stack.MajorVersion) - Eventually(container).Should(Serve(MatchRegexp(fmt.Sprintf(`v%d.*`, stack.MajorVersion))).OnPort(8080).WithEndpoint(engineVersionEndpoint)) + nodejsMajorVersion := stack.Name[len("nodejs-"):] + Eventually(container).Should(Serve(MatchRegexp(fmt.Sprintf(`v%s.*`, nodejsMajorVersion))).OnPort(8080).WithEndpoint("/nodejs/version")) }) } }) - } diff --git a/init_test.go b/init_test.go index dc4640e..3f4fdf4 100644 --- a/init_test.go +++ b/init_test.go @@ -4,11 +4,11 @@ import ( "encoding/json" "os" "path/filepath" + "strings" "testing" "time" "github.com/paketo-buildpacks/occam" - 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/sclevine/spec/report" @@ -37,7 +37,7 @@ type ImagesJson struct { SupportUsns bool `json:"support_usns"` UpdateOnNewImage bool `json:"update_on_new_image"` ReceiptsShowLimit int `json:"receipts_show_limit"` - Images []StackImages `json:"images"` + StackImages []StackImages `json:"images"` } var builder struct { @@ -70,10 +70,8 @@ var settings struct { UbiNodejsExtension string `json:"ubi-nodejs-extension"` Nodejs string `json:"nodejs"` GoDist string `json:"go-dist"` - NodeMajorVersions []int `json:"nodejs-major-versions"` } - Stacks []structs.Stack ImagesJson ImagesJson } @@ -81,10 +79,6 @@ func by(_ string, f func()) { f() } func TestAcceptance(t *testing.T) { - for _, nodeMajorVersion := range settings.Config.NodeMajorVersions { - settings.Stacks = append(settings.Stacks, structs.NewStack(nodeMajorVersion, "nodejs", root)) - } - var err error Expect := NewWithT(t).Expect @@ -108,6 +102,25 @@ func TestAcceptance(t *testing.T) { Expect(json.NewDecoder(images_json).Decode(&settings.ImagesJson)).To(Succeed()) Expect(images_json.Close()).To(Succeed()) + testOnlyStacksEnv := os.Getenv("TEST_ONLY_STACKS") + var testOnlystacks []string + + if testOnlyStacksEnv != "" { + testOnlystacks = strings.Split(testOnlyStacksEnv, " ") + } + + if len(testOnlystacks) > 0 { + var filteredStacks []StackImages + for _, stack := range settings.ImagesJson.StackImages { + for _, testStack := range testOnlystacks { + if stack.Name == testStack { + filteredStacks = append(filteredStacks, stack) + } + } + } + settings.ImagesJson.StackImages = filteredStacks + } + buildpackStore := occam.NewBuildpackStore() settings.Extensions.UbiNodejsExtension.Online, err = buildpackStore.Get. diff --git a/integration.json b/integration.json index 91286bb..e695f14 100644 --- a/integration.json +++ b/integration.json @@ -3,8 +3,5 @@ "ubi-nodejs-extension": "github.com/paketo-community/ubi-nodejs-extension", "nodejs": "github.com/paketo-buildpacks/nodejs", "go-dist": "github.com/paketo-buildpacks/go-dist", - "nodejs-major-versions": [ - 16, 18, 20 - ], "setup_local_registy": true } diff --git a/nodejs_stack_integration_test.go b/nodejs_stack_integration_test.go index 7329776..2b1d8ce 100644 --- a/nodejs_stack_integration_test.go +++ b/nodejs_stack_integration_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "regexp" "testing" "github.com/google/uuid" @@ -13,7 +14,6 @@ import ( "github.com/paketo-buildpacks/occam" . "github.com/paketo-buildpacks/occam/matchers" - structs "github.com/paketo-community/ubi-base-stack/internal/structs" utils "github.com/paketo-community/ubi-base-stack/internal/utils" ) @@ -59,18 +59,19 @@ func testNodejsStackIntegration(t *testing.T, context spec.G, it spec.S) { Expect(docker.Image.Remove.Execute(bpUbiRunImageOverrideImageID)).To(Succeed()) }) - var stacks []structs.Stack + nodejsRegex, _ := regexp.Compile("^nodejs") - 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 + for _, stack := range settings.ImagesJson.StackImages { + // Create a copy of the stack to get the value instead of a pointer stack := stack - it(fmt.Sprintf("it successfully builds an app using Nodejs %d run image", stack.MajorVersion), func() { - runArchive := filepath.Join(root, stack.Path, "run.oci") - bpUbiRunImageOverrideImageID, err = utils.PushFileToLocalRegistry(runArchive, RegistryUrl, fmt.Sprintf("run-%s-%d-%s", stack.Engine, stack.MajorVersion, uuid.NewString())) + + if !nodejsRegex.MatchString(stack.Name) { + continue + } + + it(fmt.Sprintf("it successfully builds an app using %s run image", stack.Name), func() { + runArchive := filepath.Join(root, stack.OutputDir, "run.oci") + bpUbiRunImageOverrideImageID, err = utils.PushFileToLocalRegistry(runArchive, RegistryUrl, fmt.Sprintf("run-%s-%s", stack.Name, uuid.NewString())) Expect(err).NotTo(HaveOccurred()) image, _, err = pack.Build. @@ -94,7 +95,8 @@ func testNodejsStackIntegration(t *testing.T, context spec.G, it spec.S) { Expect(err).NotTo(HaveOccurred()) Eventually(container).Should(Serve("Hello World!")) - Eventually(container).Should(Serve(MatchRegexp(fmt.Sprintf(`v%d.*`, stack.MajorVersion))).OnPort(8080).WithEndpoint("/node/version")) + nodejsMajorVersion := stack.Name[len("nodejs-"):] + Eventually(container).Should(Serve(MatchRegexp(fmt.Sprintf(`v%s.*`, nodejsMajorVersion))).OnPort(8080).WithEndpoint("/node/version")) }) } })