github.com/paketo-buildpacks/libpak/v2@v2.0.0-alpha.3.0.20231023030503-8365f81de65a/main_test.go (about) 1 /* 2 * Copyright 2018-2023 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package libpak_test 18 19 import ( 20 "os" 21 "path/filepath" 22 "testing" 23 24 "github.com/buildpacks/libcnb/v2" 25 "github.com/buildpacks/libcnb/v2/mocks" 26 . "github.com/onsi/gomega" 27 "github.com/sclevine/spec" 28 "github.com/stretchr/testify/mock" 29 30 "github.com/paketo-buildpacks/libpak/v2" 31 ) 32 33 func testMain(t *testing.T, context spec.G, it spec.S) { 34 var ( 35 Expect = NewWithT(t).Expect 36 37 applicationPath string 38 buildpackPath string 39 buildpackPlanPath string 40 buildPlanPath string 41 environmentWriter *mocks.EnvironmentWriter 42 exitHandler *mocks.ExitHandler 43 layersPath string 44 platformPath string 45 tomlWriter *mocks.TOMLWriter 46 47 workingDir string 48 ) 49 50 it.Before(func() { 51 var err error 52 53 applicationPath = t.TempDir() 54 applicationPath, err = filepath.EvalSymlinks(applicationPath) 55 Expect(err).NotTo(HaveOccurred()) 56 57 buildpackPath = t.TempDir() 58 Expect(os.Setenv("CNB_BUILDPACK_DIR", buildpackPath)).To(Succeed()) 59 60 Expect(os.Setenv("CNB_STACK_ID", "test-stack-id")).To(Succeed()) 61 62 Expect(os.WriteFile(filepath.Join(buildpackPath, "buildpack.toml"), 63 []byte(` 64 api = "0.8" 65 66 [buildpack] 67 id = "test-id" 68 name = "test-name" 69 version = "1.1.1" 70 clear-env = true 71 72 [[order]] 73 [[order.group]] 74 id = "test-id" 75 version = "2.2.2" 76 optional = true 77 78 [[stacks]] 79 id = "test-id" 80 mixins = ["test-name"] 81 82 [metadata] 83 test-key = "test-value" 84 `), 85 0644), 86 ).To(Succeed()) 87 88 f, err := os.CreateTemp("", "main-buildpackplan-path") 89 Expect(err).NotTo(HaveOccurred()) 90 Expect(f.Close()).NotTo(HaveOccurred()) 91 buildpackPlanPath = f.Name() 92 93 Expect(os.Setenv("CNB_BP_PLAN_PATH", buildpackPlanPath)).To(Succeed()) 94 95 Expect(os.WriteFile(buildpackPlanPath, 96 []byte(` 97 [[entries]] 98 name = "test-name" 99 version = "test-version" 100 101 [entries.metadata] 102 test-key = "test-value" 103 `), 104 0644), 105 ).To(Succeed()) 106 107 f, err = os.CreateTemp("", "main-buildplan-path") 108 Expect(err).NotTo(HaveOccurred()) 109 Expect(f.Close()).NotTo(HaveOccurred()) 110 buildPlanPath = f.Name() 111 112 Expect(os.Setenv("CNB_BUILD_PLAN_PATH", buildPlanPath)).To(Succeed()) 113 114 environmentWriter = &mocks.EnvironmentWriter{} 115 environmentWriter.On("Write", mock.Anything, mock.Anything).Return(nil) 116 117 exitHandler = &mocks.ExitHandler{} 118 exitHandler.On("Error", mock.Anything) 119 exitHandler.On("Pass", mock.Anything) 120 exitHandler.On("Fail", mock.Anything) 121 122 layersPath = t.TempDir() 123 124 Expect(os.Setenv("CNB_LAYERS_DIR", layersPath)).To(Succeed()) 125 126 Expect(os.WriteFile(filepath.Join(layersPath, "store.toml"), 127 []byte(` 128 [metadata] 129 test-key = "test-value" 130 `), 131 0644), 132 ).To(Succeed()) 133 134 platformPath = t.TempDir() 135 136 Expect(os.Setenv("CNB_PLATFORM_DIR", platformPath)).To(Succeed()) 137 138 Expect(os.MkdirAll(filepath.Join(platformPath, "bindings", "alpha", "metadata"), 0755)).To(Succeed()) 139 Expect(os.WriteFile( 140 filepath.Join(platformPath, "bindings", "alpha", "metadata", "test-metadata-key"), 141 []byte("test-metadata-value"), 142 0644, 143 )).To(Succeed()) 144 Expect(os.MkdirAll(filepath.Join(platformPath, "bindings", "alpha", "secret"), 0755)).To(Succeed()) 145 Expect(os.WriteFile( 146 filepath.Join(platformPath, "bindings", "alpha", "secret", "test-secret-key"), 147 []byte("test-secret-value"), 148 0644, 149 )).To(Succeed()) 150 151 Expect(os.MkdirAll(filepath.Join(platformPath, "env"), 0755)).To(Succeed()) 152 Expect(os.WriteFile(filepath.Join(platformPath, "env", "TEST_ENV"), []byte("test-value"), 0644)). 153 To(Succeed()) 154 155 tomlWriter = &mocks.TOMLWriter{} 156 tomlWriter.On("Write", mock.Anything, mock.Anything).Return(nil) 157 158 Expect(os.Setenv("CNB_STACK_ID", "test-stack-id")).To(Succeed()) 159 160 workingDir, err = os.Getwd() 161 Expect(err).NotTo(HaveOccurred()) 162 Expect(os.Chdir(applicationPath)).To(Succeed()) 163 }) 164 165 it.After(func() { 166 Expect(os.Chdir(workingDir)).To(Succeed()) 167 Expect(os.Unsetenv("CNB_STACK_ID")).To(Succeed()) 168 Expect(os.Unsetenv("CNB_BUILDPACK_DIR")).To(Succeed()) 169 Expect(os.Unsetenv("CNB_LAYERS_DIR")).To(Succeed()) 170 Expect(os.Unsetenv("CNB_PLATFORM_DIR")).To(Succeed()) 171 Expect(os.Unsetenv("CNB_BP_PLAN_PATH")).To(Succeed()) 172 Expect(os.Unsetenv("CNB_BUILD_PLAN_PATH")).To(Succeed()) 173 174 Expect(os.RemoveAll(applicationPath)).To(Succeed()) 175 Expect(os.RemoveAll(buildpackPath)).To(Succeed()) 176 Expect(os.RemoveAll(buildpackPlanPath)).To(Succeed()) 177 Expect(os.RemoveAll(layersPath)).To(Succeed()) 178 Expect(os.RemoveAll(platformPath)).To(Succeed()) 179 Expect(os.RemoveAll(buildPlanPath)).To(Succeed()) 180 }) 181 182 it("encounters the wrong number of arguments", func() { 183 detector := func(context libcnb.DetectContext) (libcnb.DetectResult, error) { 184 return libcnb.DetectResult{Pass: true}, nil 185 } 186 builder := func(context libcnb.BuildContext) (libcnb.BuildResult, error) { return libcnb.NewBuildResult(), nil } 187 188 libpak.BuildpackMain(detector, builder, 189 libcnb.WithArguments([]string{}), 190 libcnb.WithExitHandler(exitHandler), 191 ) 192 193 Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("expected command name")) 194 }) 195 196 it("calls builder for build command", func() { 197 detector := func(context libcnb.DetectContext) (libcnb.DetectResult, error) { 198 return libcnb.DetectResult{Pass: true}, nil 199 } 200 builder := func(context libcnb.BuildContext) (libcnb.BuildResult, error) { return libcnb.NewBuildResult(), nil } 201 commandPath := filepath.Join("bin", "build") 202 203 libpak.BuildpackMain(detector, builder, 204 libcnb.WithArguments([]string{commandPath, layersPath, platformPath, buildpackPlanPath}), 205 libcnb.WithExitHandler(exitHandler), 206 ) 207 208 Expect(exitHandler.Calls).To(BeEmpty()) 209 }) 210 211 it("calls detector for detect command", func() { 212 detector := func(context libcnb.DetectContext) (libcnb.DetectResult, error) { 213 return libcnb.DetectResult{Pass: true}, nil 214 } 215 builder := func(context libcnb.BuildContext) (libcnb.BuildResult, error) { return libcnb.NewBuildResult(), nil } 216 commandPath := filepath.Join("bin", "detect") 217 218 libpak.BuildpackMain(detector, builder, 219 libcnb.WithArguments([]string{commandPath, platformPath, buildPlanPath}), 220 libcnb.WithExitHandler(exitHandler), 221 ) 222 }) 223 224 it("calls exitHandler.Pass() on detection pass", func() { 225 detector := func(context libcnb.DetectContext) (libcnb.DetectResult, error) { 226 return libcnb.DetectResult{Pass: true}, nil 227 } 228 builder := func(context libcnb.BuildContext) (libcnb.BuildResult, error) { return libcnb.NewBuildResult(), nil } 229 commandPath := filepath.Join("bin", "detect") 230 231 libpak.BuildpackMain(detector, builder, 232 libcnb.WithArguments([]string{commandPath, platformPath, buildPlanPath}), 233 libcnb.WithExitHandler(exitHandler), 234 ) 235 236 Expect(exitHandler.Calls[0].Method).To(BeIdenticalTo("Pass")) 237 }) 238 239 it("calls exitHandler.Fail() on detection fail", func() { 240 detector := func(context libcnb.DetectContext) (libcnb.DetectResult, error) { 241 return libcnb.DetectResult{Pass: false}, nil 242 } 243 builder := func(context libcnb.BuildContext) (libcnb.BuildResult, error) { return libcnb.NewBuildResult(), nil } 244 commandPath := filepath.Join("bin", "detect") 245 246 libpak.BuildpackMain(detector, builder, 247 libcnb.WithArguments([]string{commandPath, platformPath, buildPlanPath}), 248 libcnb.WithExitHandler(exitHandler), 249 ) 250 251 Expect(exitHandler.Calls[0].Method).To(BeIdenticalTo("Fail")) 252 }) 253 254 it("encounters an unknown command", func() { 255 detector := func(context libcnb.DetectContext) (libcnb.DetectResult, error) { 256 return libcnb.DetectResult{Pass: true}, nil 257 } 258 builder := func(context libcnb.BuildContext) (libcnb.BuildResult, error) { return libcnb.NewBuildResult(), nil } 259 commandPath := filepath.Join("bin", "test-command") 260 261 libpak.BuildpackMain(detector, builder, 262 libcnb.WithArguments([]string{commandPath}), 263 libcnb.WithExitHandler(exitHandler), 264 ) 265 266 Expect(exitHandler.Calls[0].Arguments.Get(0)).To(MatchError("unsupported command test-command")) 267 }) 268 269 }