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  }