github.com/paketo-buildpacks/packit@v1.3.2-0.20211206231111-86b75c657449/pexec/executable_test.go (about)

     1  package pexec_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/sclevine/spec"
    11  
    12  	"github.com/onsi/gomega/gexec"
    13  	"github.com/paketo-buildpacks/packit/pexec"
    14  
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  func testPexec(t *testing.T, context spec.G, it spec.S) {
    19  	var (
    20  		Expect = NewWithT(t).Expect
    21  
    22  		tmpDir         string
    23  		stdout, stderr *bytes.Buffer
    24  
    25  		executable pexec.Executable
    26  	)
    27  
    28  	it.Before(func() {
    29  		var err error
    30  		tmpDir, err = os.MkdirTemp("", "executable")
    31  		Expect(err).NotTo(HaveOccurred())
    32  
    33  		tmpDir, err = filepath.EvalSymlinks(tmpDir)
    34  		Expect(err).NotTo(HaveOccurred())
    35  
    36  		stdout = bytes.NewBuffer(nil)
    37  		stderr = bytes.NewBuffer(nil)
    38  
    39  		executable = pexec.NewExecutable(filepath.Base(fakeCLI))
    40  	})
    41  
    42  	it.After(func() {
    43  		Expect(os.RemoveAll(tmpDir)).To(Succeed())
    44  	})
    45  
    46  	context("Execute", func() {
    47  		it("executes the given arguments against the executable", func() {
    48  			err := executable.Execute(pexec.Execution{
    49  				Args:   []string{"something"},
    50  				Stdout: stdout,
    51  			})
    52  			Expect(err).NotTo(HaveOccurred())
    53  			Expect(stdout).To(ContainSubstring(fmt.Sprintf("Arguments: [%s something]", fakeCLI)))
    54  		})
    55  
    56  		context("when given a execution directory", func() {
    57  			it("executes within that directory", func() {
    58  				err := executable.Execute(pexec.Execution{
    59  					Dir:    tmpDir,
    60  					Stdout: stdout,
    61  				})
    62  				Expect(err).NotTo(HaveOccurred())
    63  				Expect(stdout).To(ContainSubstring(fmt.Sprintf("PWD=%s", tmpDir)))
    64  			})
    65  		})
    66  
    67  		context("when given an execution environment", func() {
    68  			it("executes with that environment", func() {
    69  				err := executable.Execute(pexec.Execution{
    70  					Env:    []string{"SOME_KEY=some-value"},
    71  					Stdout: stdout,
    72  				})
    73  				Expect(err).NotTo(HaveOccurred())
    74  				Expect(stdout).To(ContainSubstring("SOME_KEY=some-value"))
    75  			})
    76  		})
    77  
    78  		context("when given a writer for stdout and stderr", func() {
    79  			it("pipes stdout to that writer", func() {
    80  				err := executable.Execute(pexec.Execution{
    81  					Stdout: stdout,
    82  					Stderr: stderr,
    83  				})
    84  				Expect(err).NotTo(HaveOccurred())
    85  
    86  				Expect(stdout).To(ContainSubstring("Output on stdout"))
    87  				Expect(stderr).To(ContainSubstring("Output on stderr"))
    88  			})
    89  		})
    90  
    91  		context("when the executable is on the PATH given as an argument", func() {
    92  			it.Before(func() {
    93  				os.Setenv("PATH", "some-path")
    94  			})
    95  
    96  			it("executes the given arguments against the executable", func() {
    97  				err := executable.Execute(pexec.Execution{
    98  					Args:   []string{"something"},
    99  					Env:    []string{fmt.Sprintf("PATH=%s", filepath.Dir(fakeCLI))},
   100  					Stdout: stdout,
   101  				})
   102  				Expect(err).NotTo(HaveOccurred())
   103  				Expect(stdout).To(ContainSubstring(fmt.Sprintf("Arguments: [%s something]", fakeCLI)))
   104  				Expect(os.Getenv("PATH")).To(Equal("some-path"))
   105  			})
   106  		})
   107  
   108  		context("failure cases", func() {
   109  			context("when the executable cannot be found on the path", func() {
   110  				it.Before(func() {
   111  					executable = pexec.NewExecutable("unknown-executable")
   112  				})
   113  
   114  				it("returns an error", func() {
   115  					err := executable.Execute(pexec.Execution{})
   116  					Expect(err).To(MatchError("exec: \"unknown-executable\": executable file not found in $PATH"))
   117  				})
   118  			})
   119  
   120  			context("when the executable errors", func() {
   121  				var (
   122  					errorCLI string
   123  					path     string
   124  				)
   125  
   126  				it.Before(func() {
   127  					Expect(os.Setenv("PATH", existingPath)).To(Succeed())
   128  
   129  					var err error
   130  					errorCLI, err = gexec.Build("github.com/paketo-buildpacks/packit/fakes/some-executable", "-ldflags", "-X main.fail=true")
   131  					Expect(err).NotTo(HaveOccurred())
   132  
   133  					path = os.Getenv("PATH")
   134  					Expect(os.Setenv("PATH", filepath.Dir(errorCLI))).To(Succeed())
   135  				})
   136  
   137  				it.After(func() {
   138  					Expect(os.Setenv("PATH", path)).To(Succeed())
   139  				})
   140  
   141  				it("executes the given arguments against the executable", func() {
   142  					err := executable.Execute(pexec.Execution{
   143  						Args:   []string{"something"},
   144  						Stdout: stdout,
   145  						Stderr: stderr,
   146  					})
   147  					Expect(err).To(MatchError("exit status 1"))
   148  					Expect(stdout).To(ContainSubstring("Error on stdout"))
   149  					Expect(stderr).To(ContainSubstring("Error on stderr"))
   150  				})
   151  			})
   152  		})
   153  	})
   154  
   155  }