...

Source file src/github.com/redhat-developer/odo/tests/helper/helper_cmd_wrapper.go

Documentation: github.com/redhat-developer/odo/tests/helper

     1  package helper
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"runtime"
     9  	"time"
    10  
    11  	. "github.com/onsi/ginkgo/v2"
    12  	. "github.com/onsi/gomega"
    13  	"github.com/onsi/gomega/gexec"
    14  )
    15  
    16  type CmdWrapper struct {
    17  	Cmd             *exec.Cmd
    18  	program         string
    19  	args            []string
    20  	writer          *gexec.PrefixedWriter
    21  	session         *gexec.Session
    22  	timeout         time.Duration
    23  	intervalSeconds time.Duration
    24  	stopChan        chan bool
    25  	err             error
    26  	maxRetry        int
    27  	pass            bool
    28  }
    29  
    30  func Cmd(program string, args ...string) *CmdWrapper {
    31  	prefix := fmt.Sprintf("[%s] ", filepath.Base(program))
    32  	prefixWriter := gexec.NewPrefixedWriter(prefix, GinkgoWriter)
    33  	command := exec.Command(program, args...)
    34  	setSysProcAttr(command)
    35  	return &CmdWrapper{
    36  		Cmd:     command,
    37  		program: program,
    38  		args:    args,
    39  		writer:  prefixWriter,
    40  	}
    41  }
    42  
    43  func (cw *CmdWrapper) Runner() *CmdWrapper {
    44  	fmt.Fprintln(GinkgoWriter, runningCmd(cw.Cmd))
    45  	cw.session, cw.err = gexec.Start(cw.Cmd, cw.writer, cw.writer)
    46  	timeout := time.After(cw.timeout)
    47  	if cw.timeout > 0 {
    48  		select {
    49  		case <-cw.stopChan:
    50  			if cw.session != nil {
    51  				if runtime.GOOS == "windows" {
    52  					cw.session.Kill()
    53  				} else {
    54  					cw.session.Terminate()
    55  				}
    56  			}
    57  		case <-timeout:
    58  			if cw.session != nil {
    59  				if runtime.GOOS == "windows" {
    60  					cw.session.Kill()
    61  				} else {
    62  					cw.session.Terminate()
    63  				}
    64  			}
    65  		}
    66  	} else if cw.maxRetry > 0 {
    67  		cw.session.Wait()
    68  		// cw.pass is to check if it is used with ShouldPass Or ShouldFail
    69  		if !cw.pass {
    70  			// we retry on success because the user has set “ShouldFail” as true
    71  			// if exit code is 0 which means the program succeeded and hence we retry
    72  			if cw.session.ExitCode() == 0 {
    73  				time.Sleep(cw.intervalSeconds * time.Second)
    74  				cw.maxRetry = cw.maxRetry - 1
    75  				cw.Runner()
    76  			}
    77  			return cw
    78  		} else {
    79  			// if exit code is not 0 which means the program Failed and hence we retry
    80  			if cw.session.ExitCode() != 0 {
    81  				time.Sleep(cw.intervalSeconds * time.Second)
    82  				cw.maxRetry = cw.maxRetry - 1
    83  				cw.Runner()
    84  			}
    85  			return cw
    86  		}
    87  	}
    88  	return cw
    89  }
    90  
    91  func (cw *CmdWrapper) WithRetry(maxRetry int, intervalSeconds time.Duration) *CmdWrapper {
    92  	cw.maxRetry = maxRetry
    93  	cw.intervalSeconds = intervalSeconds
    94  	return cw
    95  }
    96  
    97  func (cw *CmdWrapper) ShouldPass() *CmdWrapper {
    98  	cw.pass = true
    99  	cw.Runner()
   100  	Expect(cw.err).NotTo(HaveOccurred())
   101  	Eventually(cw.session).Should(gexec.Exit(0), runningCmd(cw.session.Command))
   102  	return cw
   103  }
   104  
   105  func (cw *CmdWrapper) ShouldFail() *CmdWrapper {
   106  	cw.pass = false
   107  	cw.Runner()
   108  	Consistently(cw.session).ShouldNot(gexec.Exit(0), runningCmd(cw.session.Command))
   109  	return cw
   110  }
   111  
   112  func (cw *CmdWrapper) ShouldRun() *CmdWrapper {
   113  	cw.Runner()
   114  	return cw
   115  }
   116  
   117  func (cw *CmdWrapper) Should(f func(session *gexec.Session)) {
   118  	cw.Runner()
   119  	f(cw.session)
   120  	cw.session.Wait()
   121  }
   122  
   123  func (cw *CmdWrapper) WithTerminate(timeoutAfter time.Duration, stop chan bool) *CmdWrapper {
   124  	cw.timeout = timeoutAfter * time.Second
   125  	cw.stopChan = stop
   126  	return cw
   127  }
   128  
   129  func (cw *CmdWrapper) WithTimeout(timeoutAfter time.Duration) *CmdWrapper {
   130  	cw.timeout = timeoutAfter * time.Second
   131  	return cw
   132  }
   133  
   134  func (cw *CmdWrapper) WithWorkingDir(dir string) *CmdWrapper {
   135  	cw.Cmd.Dir = dir
   136  	return cw
   137  }
   138  
   139  func (cw *CmdWrapper) WithEnv(args ...string) *CmdWrapper {
   140  	cw.Cmd.Env = args
   141  	return cw
   142  }
   143  
   144  func (cw *CmdWrapper) AddEnv(args ...string) *CmdWrapper {
   145  	if cw.Cmd.Env == nil {
   146  		cw.Cmd.Env = append(cw.Cmd.Env, os.Environ()...)
   147  	}
   148  	cw.Cmd.Env = append(cw.Cmd.Env, args...)
   149  	return cw
   150  }
   151  
   152  func (cw *CmdWrapper) OutAndErr() (string, string) {
   153  	return string(cw.session.Wait().Out.Contents()), string(cw.session.Wait().Err.Contents())
   154  }
   155  
   156  func (cw *CmdWrapper) Out() string {
   157  	return string(cw.session.Wait().Out.Contents())
   158  }
   159  
   160  func (cw *CmdWrapper) Err() string {
   161  	return string(cw.session.Wait().Err.Contents())
   162  }
   163  

View as plain text