github.com/ahlemtn/fabric@v2.1.1+incompatible/core/container/externalbuilder/session_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package externalbuilder_test
     8  
     9  import (
    10  	"io"
    11  	"os/exec"
    12  	"syscall"
    13  
    14  	"github.com/hyperledger/fabric/common/flogging"
    15  	"github.com/hyperledger/fabric/core/container/externalbuilder"
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/gomega"
    18  	"github.com/onsi/gomega/gbytes"
    19  	"go.uber.org/zap"
    20  	"go.uber.org/zap/zapcore"
    21  )
    22  
    23  var _ = Describe("Session", func() {
    24  	var (
    25  		logbuf *gbytes.Buffer
    26  		logger *flogging.FabricLogger
    27  	)
    28  
    29  	BeforeEach(func() {
    30  		logbuf = gbytes.NewBuffer()
    31  		writer := io.MultiWriter(logbuf, GinkgoWriter)
    32  		enc := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{MessageKey: "msg"})
    33  		core := zapcore.NewCore(enc, zapcore.AddSync(writer), zap.NewAtomicLevel())
    34  		logger = flogging.NewFabricLogger(zap.New(core).Named("logger"))
    35  	})
    36  
    37  	It("starts commands and returns a session handle to wait on", func() {
    38  		cmd := exec.Command("true")
    39  		sess, err := externalbuilder.Start(logger, cmd)
    40  		Expect(err).NotTo(HaveOccurred())
    41  		Expect(sess).NotTo(BeNil())
    42  
    43  		err = sess.Wait()
    44  		Expect(err).NotTo(HaveOccurred())
    45  	})
    46  
    47  	It("captures stderr to the provided logger", func() {
    48  		cmd := exec.Command("sh", "-c", "echo 'this is a message to stderr' >&2")
    49  		sess, err := externalbuilder.Start(logger, cmd)
    50  		Expect(err).NotTo(HaveOccurred())
    51  		err = sess.Wait()
    52  		Expect(err).NotTo(HaveOccurred())
    53  
    54  		Expect(logbuf).To(gbytes.Say("this is a message to stderr"))
    55  	})
    56  
    57  	It("delivers signals to started commands", func() {
    58  		cmd := exec.Command("cat")
    59  		stdin, err := cmd.StdinPipe()
    60  		Expect(err).NotTo(HaveOccurred())
    61  		defer stdin.Close()
    62  
    63  		sess, err := externalbuilder.Start(logger, cmd)
    64  		Expect(err).NotTo(HaveOccurred())
    65  
    66  		exitCh := make(chan error)
    67  		go func() { exitCh <- sess.Wait() }()
    68  
    69  		Consistently(exitCh).ShouldNot(Receive())
    70  		sess.Signal(syscall.SIGTERM)
    71  		Eventually(exitCh).Should(Receive(MatchError("signal: terminated")))
    72  	})
    73  
    74  	When("start fails", func() {
    75  		It("returns an error", func() {
    76  			cmd := exec.Command("./this-is-not-a-command")
    77  			_, err := externalbuilder.Start(logger, cmd)
    78  			Expect(err).To(MatchError("fork/exec ./this-is-not-a-command: no such file or directory"))
    79  		})
    80  	})
    81  
    82  	When("the command fails", func() {
    83  		It("returns the exit error from the command", func() {
    84  			cmd := exec.Command("false")
    85  			sess, err := externalbuilder.Start(logger, cmd)
    86  			Expect(err).NotTo(HaveOccurred())
    87  
    88  			err = sess.Wait()
    89  			Expect(err).To(MatchError("exit status 1"))
    90  			Expect(err).To(BeAssignableToTypeOf(&exec.ExitError{}))
    91  		})
    92  	})
    93  })