From f67aecd5007783c17709334da9dd5a97929ceb9d Mon Sep 17 00:00:00 2001 From: Sebastian Nickel Date: Tue, 28 Nov 2023 13:19:33 +0100 Subject: [PATCH] fix cached layer tests --- build_test.go | 130 ++++++++++++++---------- integration/framework_app_test.go | 5 +- integration/reuse_layer_rebuild_test.go | 116 +++++++++++++++++---- 3 files changed, 171 insertions(+), 80 deletions(-) diff --git a/build_test.go b/build_test.go index 80e98790..0ae9a609 100644 --- a/build_test.go +++ b/build_test.go @@ -384,40 +384,48 @@ composer-lock-sha = "sha-from-composer-lock" Expect(os.RemoveAll(filepath.Join(layersDir, composer.ComposerPackagesLayerName))).To(Succeed()) }) - it("reuses the cached version of the composer packages", func() { - result, err := build(packit.BuildContext{ - BuildpackInfo: buildpackInfo, - WorkingDir: workingDir, - Layers: packit.Layers{Path: layersDir}, - Plan: buildpackPlan, + context("with BP_RUN_COMPOSER_INSTALL set to false", func() { + it.Before(func() { + Expect(os.Setenv("BP_RUN_COMPOSER_INSTALL", "false")).To(Succeed()) + }) + it.After(func() { + Expect(os.Unsetenv("BP_RUN_COMPOSER_INSTALL")).To(Succeed()) }) - Expect(err).NotTo(HaveOccurred()) - Expect(buffer).NotTo(ContainSubstring("Running 'composer install options from fake'")) + it("reuses the cached version of the composer packages", func() { + result, err := build(packit.BuildContext{ + BuildpackInfo: buildpackInfo, + WorkingDir: workingDir, + Layers: packit.Layers{Path: layersDir}, + Plan: buildpackPlan, + }) + Expect(err).NotTo(HaveOccurred()) - Expect(calculator.SumCall.Receives.Paths).To(Equal([]string{filepath.Join(workingDir, "composer.lock")})) - layers := result.Layers - Expect(layers).To(HaveLen(1)) + Expect(buffer).NotTo(ContainSubstring("Running 'composer install options from fake'")) - packagesLayer := layers[0] - Expect(packagesLayer.Name).To(Equal(composer.ComposerPackagesLayerName)) - Expect(packagesLayer.Path).To(Equal(filepath.Join(layersDir, composer.ComposerPackagesLayerName))) + Expect(calculator.SumCall.Receives.Paths).To(Equal([]string{filepath.Join(workingDir, "composer.lock")})) + layers := result.Layers + Expect(layers).To(HaveLen(1)) - Expect(packagesLayer.Build).To(BeTrue()) - Expect(packagesLayer.Launch).To(BeTrue()) - Expect(packagesLayer.Cache).To(BeTrue()) + packagesLayer := layers[0] + Expect(packagesLayer.Name).To(Equal(composer.ComposerPackagesLayerName)) + Expect(packagesLayer.Path).To(Equal(filepath.Join(layersDir, composer.ComposerPackagesLayerName))) - Expect(packagesLayer.Metadata["composer-lock-sha"]).To(Equal("sha-from-composer-lock")) - Expect(packagesLayer.Metadata["stack"]).To(Equal("")) + Expect(packagesLayer.Build).To(BeTrue()) + Expect(packagesLayer.Launch).To(BeTrue()) + Expect(packagesLayer.Cache).To(BeTrue()) - Expect(packagesLayer.SBOM.Formats()).To(HaveLen(2)) - cdx := packagesLayer.SBOM.Formats()[0] - spdx := packagesLayer.SBOM.Formats()[1] + Expect(packagesLayer.Metadata["composer-lock-sha"]).To(Equal("sha-from-composer-lock")) + Expect(packagesLayer.Metadata["stack"]).To(Equal("")) - Expect(cdx.Extension).To(Equal("cdx.json")) - content, err := io.ReadAll(cdx.Content) - Expect(err).NotTo(HaveOccurred()) - Expect(string(content)).To(MatchJSON(`{ + Expect(packagesLayer.SBOM.Formats()).To(HaveLen(2)) + cdx := packagesLayer.SBOM.Formats()[0] + spdx := packagesLayer.SBOM.Formats()[1] + + Expect(cdx.Extension).To(Equal("cdx.json")) + content, err := io.ReadAll(cdx.Content) + Expect(err).NotTo(HaveOccurred()) + Expect(string(content)).To(MatchJSON(`{ "bomFormat": "CycloneDX", "components": [], "metadata": { @@ -433,10 +441,10 @@ composer-lock-sha = "sha-from-composer-lock" "version": 1 }`)) - Expect(spdx.Extension).To(Equal("spdx.json")) - content, err = io.ReadAll(spdx.Content) - Expect(err).NotTo(HaveOccurred()) - Expect(string(content)).To(MatchJSON(`{ + Expect(spdx.Extension).To(Equal("spdx.json")) + content, err = io.ReadAll(spdx.Content) + Expect(err).NotTo(HaveOccurred()) + Expect(string(content)).To(MatchJSON(`{ "SPDXID": "SPDXRef-DOCUMENT", "creationInfo": { "created": "0001-01-01T00:00:00Z", @@ -459,7 +467,8 @@ composer-lock-sha = "sha-from-composer-lock" "spdxVersion": "SPDX-2.2" }`)) - Expect(filepath.Join(workingDir, "vendor", "file.txt")).To(BeAnExistingFile()) + Expect(filepath.Join(workingDir, "vendor", "file.txt")).To(BeAnExistingFile()) + }) }) context("when trying to reuse a layer but the stack changes", func() { @@ -498,33 +507,42 @@ composer-lock-sha = "sha-from-composer-lock" Expect(os.WriteFile(filepath.Join(workingDir, "vendor", "pre-existing-file.text"), []byte(""), os.ModePerm)).To(Succeed()) }) - it("replaces workspace vendor directory with cached vendor directory", func() { - result, err := build(packit.BuildContext{ - BuildpackInfo: buildpackInfo, - WorkingDir: workingDir, - Layers: packit.Layers{Path: layersDir}, - Plan: buildpackPlan, + context("with BP_RUN_COMPOSER_INSTALL set to false", func() { + it.Before(func() { + Expect(os.Setenv("BP_RUN_COMPOSER_INSTALL", "false")).To(Succeed()) + }) + it.After(func() { + Expect(os.Unsetenv("BP_RUN_COMPOSER_INSTALL")).To(Succeed()) }) - Expect(err).NotTo(HaveOccurred()) - Expect(buffer).NotTo(ContainSubstring("Running 'composer install options from fake'")) - - Expect(calculator.SumCall.Receives.Paths).To(Equal([]string{filepath.Join(workingDir, "composer.lock")})) - layers := result.Layers - Expect(layers).To(HaveLen(1)) - - packagesLayer := layers[0] - Expect(packagesLayer.Name).To(Equal(composer.ComposerPackagesLayerName)) - Expect(packagesLayer.Path).To(Equal(filepath.Join(layersDir, composer.ComposerPackagesLayerName))) - - Expect(packagesLayer.Build).To(BeTrue()) - Expect(packagesLayer.Launch).To(BeTrue()) - Expect(packagesLayer.Cache).To(BeTrue()) - - Expect(packagesLayer.Metadata["composer-lock-sha"]).To(Equal("sha-from-composer-lock")) - Expect(packagesLayer.Metadata["stack"]).To(Equal("")) - Expect(filepath.Join(workingDir, "vendor", "file.txt")).To(BeAnExistingFile()) - Expect(filepath.Join(workingDir, "vendor", "pre-existing-file.text")).NotTo(BeAnExistingFile()) + it("replaces workspace vendor directory with cached vendor directory", func() { + result, err := build(packit.BuildContext{ + BuildpackInfo: buildpackInfo, + WorkingDir: workingDir, + Layers: packit.Layers{Path: layersDir}, + Plan: buildpackPlan, + }) + Expect(err).NotTo(HaveOccurred()) + Expect(buffer).NotTo(ContainSubstring("Running 'composer install options from fake'")) + + Expect(calculator.SumCall.Receives.Paths).To(Equal([]string{filepath.Join(workingDir, "composer.lock")})) + layers := result.Layers + Expect(layers).To(HaveLen(1)) + + packagesLayer := layers[0] + Expect(packagesLayer.Name).To(Equal(composer.ComposerPackagesLayerName)) + Expect(packagesLayer.Path).To(Equal(filepath.Join(layersDir, composer.ComposerPackagesLayerName))) + + Expect(packagesLayer.Build).To(BeTrue()) + Expect(packagesLayer.Launch).To(BeTrue()) + Expect(packagesLayer.Cache).To(BeTrue()) + + Expect(packagesLayer.Metadata["composer-lock-sha"]).To(Equal("sha-from-composer-lock")) + Expect(packagesLayer.Metadata["stack"]).To(Equal("")) + + Expect(filepath.Join(workingDir, "vendor", "file.txt")).To(BeAnExistingFile()) + Expect(filepath.Join(workingDir, "vendor", "pre-existing-file.text")).NotTo(BeAnExistingFile()) + }) }) }) }) diff --git a/integration/framework_app_test.go b/integration/framework_app_test.go index 98cee45b..6ef02700 100644 --- a/integration/framework_app_test.go +++ b/integration/framework_app_test.go @@ -120,8 +120,8 @@ func testFrameworkApps(t *testing.T, context spec.G, it spec.S) { context("building a drupal app", func() { var ( - err error - logs fmt.Stringer + err error + logs fmt.Stringer secondImage occam.Image ) @@ -150,7 +150,6 @@ func testFrameworkApps(t *testing.T, context spec.G, it spec.S) { "BP_PHP_SERVER": "nginx", "BP_PHP_WEB_DIR": "web", "BP_LOG_LEVEL": "DEBUG", - "BP_RUN_COMPOSER_INSTALL": "1", }). Execute(name, source) diff --git a/integration/reuse_layer_rebuild_test.go b/integration/reuse_layer_rebuild_test.go index 3511985c..0d55587c 100644 --- a/integration/reuse_layer_rebuild_test.go +++ b/integration/reuse_layer_rebuild_test.go @@ -53,6 +53,7 @@ func testReusingLayerRebuild(t *testing.T, context spec.G, it spec.S) { logs fmt.Stringer firstImage occam.Image secondImage occam.Image + thirdImage occam.Image ) source, err = occam.Source(filepath.Join("testdata", "default_app")) @@ -77,21 +78,56 @@ func testReusingLayerRebuild(t *testing.T, context spec.G, it spec.S) { Expect(logs.String()).To(ContainSubstring("Running 'composer install --no-progress --no-dev'")) - // Second pack build - secondImage, logs, err = build.Execute(name, source) - Expect(err).NotTo(HaveOccurred()) + // Second pack build with BP_RUN_COMPOSER_INSTALL set to false + context("with BP_RUN_COMPOSER_INSTALL set to false", func() { + it.Before(func() { + Expect(os.Setenv("BP_RUN_COMPOSER_INSTALL", "false")).To(Succeed()) + }) + it.After(func() { + Expect(os.Unsetenv("BP_RUN_COMPOSER_INSTALL")).To(Succeed()) + }) + secondImage, logs, err = build.Execute(name, source) + Expect(err).NotTo(HaveOccurred()) - imageIDs[secondImage.ID] = struct{}{} + imageIDs[secondImage.ID] = struct{}{} - Expect(secondImage.Buildpacks).To(HaveLen(7)) + Expect(secondImage.Buildpacks).To(HaveLen(7)) - Expect(secondImage.Buildpacks[2].Key).To(Equal(buildpackInfo.Buildpack.ID)) - Expect(secondImage.Buildpacks[2].Layers).To(HaveKey("composer-packages")) + Expect(secondImage.Buildpacks[2].Key).To(Equal(buildpackInfo.Buildpack.ID)) + Expect(secondImage.Buildpacks[2].Layers).To(HaveKey("composer-packages")) - Expect(logs.String()).NotTo(ContainSubstring("Running 'composer install --no-progress --no-dev'")) - Expect(logs.String()).To(ContainSubstring(fmt.Sprintf("Reusing cached layer /layers/%s/composer-packages", strings.ReplaceAll(buildpackInfo.Buildpack.ID, "/", "_")))) + it("it does not run composer install again", func() { + Expect(logs.String()).NotTo(ContainSubstring("Running 'composer install --no-progress --no-dev'")) + }) + Expect(logs.String()).To(ContainSubstring(fmt.Sprintf("Reusing cached layer /layers/%s/composer-packages", strings.ReplaceAll(buildpackInfo.Buildpack.ID, "/", "_")))) + Expect(secondImage.Buildpacks[2].Layers["composer-packages"].SHA).To(Equal(firstImage.Buildpacks[2].Layers["composer-packages"].SHA)) + }) + + // Third pack build with BP_RUN_COMPOSER_INSTALL set to true + context("with BP_RUN_COMPOSER_INSTALL set to true", func() { + it.Before(func() { + Expect(os.Setenv("BP_RUN_COMPOSER_INSTALL", "true")).To(Succeed()) + }) + it.After(func() { + Expect(os.Unsetenv("BP_RUN_COMPOSER_INSTALL")).To(Succeed()) + }) + thirdImage, logs, err = build.Execute(name, source) + Expect(err).NotTo(HaveOccurred()) + + imageIDs[thirdImage.ID] = struct{}{} + + Expect(thirdImage.Buildpacks).To(HaveLen(7)) - Expect(secondImage.Buildpacks[2].Layers["composer-packages"].SHA).To(Equal(firstImage.Buildpacks[2].Layers["composer-packages"].SHA)) + Expect(thirdImage.Buildpacks[2].Key).To(Equal(buildpackInfo.Buildpack.ID)) + Expect(thirdImage.Buildpacks[2].Layers).To(HaveKey("composer-packages")) + + it("it does run composer install again", func() { + Expect(logs.String()).To(ContainSubstring("Running 'composer install --no-progress --no-dev'")) + }) + Expect(logs.String()).To(ContainSubstring(fmt.Sprintf("Reusing cached layer /layers/%s/composer-packages", strings.ReplaceAll(buildpackInfo.Buildpack.ID, "/", "_")))) + + Expect(thirdImage.Buildpacks[2].Layers["composer-packages"].SHA).To(Equal(firstImage.Buildpacks[2].Layers["composer-packages"].SHA)) + }) }) }) @@ -155,6 +191,7 @@ func testReusingLayerRebuild(t *testing.T, context spec.G, it spec.S) { logs fmt.Stringer firstImage occam.Image secondImage occam.Image + thirdImage occam.Image ) source, err = occam.Source(filepath.Join("testdata", "with_vendored_packages")) @@ -179,22 +216,59 @@ func testReusingLayerRebuild(t *testing.T, context spec.G, it spec.S) { Expect(logs.String()).To(ContainSubstring("Running 'composer install --no-progress --no-dev'")) - // Second pack build - secondImage, logs, err = build.Execute(name, source) - Expect(err).NotTo(HaveOccurred()) + // Second pack build with BP_RUN_COMPOSER_INSTALL set to false + context("with BP_RUN_COMPOSER_INSTALL set to false", func() { + it.Before(func() { + Expect(os.Setenv("BP_RUN_COMPOSER_INSTALL", "false")).To(Succeed()) + }) + it.After(func() { + Expect(os.Unsetenv("BP_RUN_COMPOSER_INSTALL")).To(Succeed()) + }) + secondImage, logs, err = build.Execute(name, source) + Expect(err).NotTo(HaveOccurred()) - imageIDs[secondImage.ID] = struct{}{} + imageIDs[secondImage.ID] = struct{}{} - Expect(secondImage.Buildpacks).To(HaveLen(7)) + Expect(secondImage.Buildpacks).To(HaveLen(7)) - Expect(secondImage.Buildpacks[2].Key).To(Equal(buildpackInfo.Buildpack.ID)) - Expect(secondImage.Buildpacks[2].Layers).To(HaveKey("composer-packages")) + Expect(secondImage.Buildpacks[2].Key).To(Equal(buildpackInfo.Buildpack.ID)) + Expect(secondImage.Buildpacks[2].Layers).To(HaveKey("composer-packages")) + + it("does not run composer install again", func() { + Expect(logs.String()).NotTo(ContainSubstring("Running 'composer install --no-progress --no-dev'")) + }) + Expect(logs.String()).To(ContainSubstring("Detected existing vendored packages, replacing with cached vendored packages")) + Expect(logs.String()).To(ContainSubstring(fmt.Sprintf("Reusing cached layer /layers/%s/composer-packages", strings.ReplaceAll(buildpackInfo.Buildpack.ID, "/", "_")))) - Expect(logs.String()).NotTo(ContainSubstring("Running 'composer install --no-progress --no-dev'")) - Expect(logs.String()).To(ContainSubstring("Detected existing vendored packages, replacing with cached vendored packages")) - Expect(logs.String()).To(ContainSubstring(fmt.Sprintf("Reusing cached layer /layers/%s/composer-packages", strings.ReplaceAll(buildpackInfo.Buildpack.ID, "/", "_")))) + Expect(secondImage.Buildpacks[2].Layers["composer-packages"].SHA).To(Equal(firstImage.Buildpacks[2].Layers["composer-packages"].SHA)) + }) + + // Third pack build with BP_RUN_COMPOSER_INSTALL set to true + context("with BP_RUN_COMPOSER_INSTALL set to true", func() { + it.Before(func() { + Expect(os.Setenv("BP_RUN_COMPOSER_INSTALL", "true")).To(Succeed()) + }) + it.After(func() { + Expect(os.Unsetenv("BP_RUN_COMPOSER_INSTALL")).To(Succeed()) + }) + thirdImage, logs, err = build.Execute(name, source) + Expect(err).NotTo(HaveOccurred()) + + imageIDs[thirdImage.ID] = struct{}{} + + Expect(thirdImage.Buildpacks).To(HaveLen(7)) + + Expect(thirdImage.Buildpacks[2].Key).To(Equal(buildpackInfo.Buildpack.ID)) + Expect(thirdImage.Buildpacks[2].Layers).To(HaveKey("composer-packages")) + + it("does run composer install again", func() { + Expect(logs.String()).To(ContainSubstring("Running 'composer install --no-progress --no-dev'")) + }) + Expect(logs.String()).To(ContainSubstring("Detected existing vendored packages, replacing with cached vendored packages")) + Expect(logs.String()).To(ContainSubstring(fmt.Sprintf("Reusing cached layer /layers/%s/composer-packages", strings.ReplaceAll(buildpackInfo.Buildpack.ID, "/", "_")))) - Expect(secondImage.Buildpacks[2].Layers["composer-packages"].SHA).To(Equal(firstImage.Buildpacks[2].Layers["composer-packages"].SHA)) + Expect(thirdImage.Buildpacks[2].Layers["composer-packages"].SHA).To(Equal(firstImage.Buildpacks[2].Layers["composer-packages"].SHA)) + }) }) }) }