github.com/Equinix-Metal/virtlet@v1.5.2-0.20210807010419-342346535dc5/tests/e2e/framework/localcmd_interface.go (about)

     1  package framework
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"io"
     7  	"os/exec"
     8  	"syscall"
     9  )
    10  
    11  type LocalCmd struct {
    12  	ctx context.Context
    13  }
    14  
    15  func LocalExecutor(ctx context.Context) *LocalCmd {
    16  	return &LocalCmd{ctx: ctx}
    17  }
    18  
    19  var _ Executor = &LocalCmd{}
    20  
    21  func (l *LocalCmd) Run(stdin io.Reader, stdout, stderr io.Writer, command ...string) error {
    22  	cmd := exec.CommandContext(l.ctx, command[0], command[1:]...)
    23  	cmd.Stdin = stdin
    24  	cmd.Stdout = stdout
    25  	cmd.Stderr = stderr
    26  
    27  	if err := cmd.Run(); err != nil {
    28  		if exiterr, ok := err.(*exec.ExitError); ok {
    29  			if s, ok := exiterr.Sys().(syscall.WaitStatus); ok {
    30  				return CommandError{ExitCode: s.ExitStatus()}
    31  			}
    32  		}
    33  		return err
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  func (l *LocalCmd) Start(stdin io.Reader, stdout, stderr io.Writer, command ...string) (Command, error) {
    40  	cmd := exec.CommandContext(l.ctx, command[0], command[1:]...)
    41  	cmd.Stdin = stdin
    42  	cmd.Stdout = stdout
    43  	cmd.Stderr = stderr
    44  
    45  	if err := cmd.Start(); err != nil {
    46  		return nil, err
    47  	}
    48  
    49  	return localCommand{cmd: cmd}, nil
    50  }
    51  
    52  func (l *LocalCmd) Close() error {
    53  	return nil
    54  }
    55  
    56  // Logs is a placeholder for fulfilling Executor interface
    57  func (l *LocalCmd) Logs() (string, error) {
    58  	return "", errors.New("not implemented")
    59  }
    60  
    61  type localCommand struct {
    62  	cmd *exec.Cmd
    63  }
    64  
    65  var _ Command = &localCommand{}
    66  
    67  func (c localCommand) Wait() error {
    68  	if err := c.cmd.Wait(); err != nil {
    69  		if exiterr, ok := err.(*exec.ExitError); ok {
    70  			if s, ok := exiterr.Sys().(syscall.WaitStatus); ok {
    71  				return CommandError{ExitCode: s.ExitStatus()}
    72  			}
    73  		}
    74  		return err
    75  	}
    76  
    77  	return nil
    78  }
    79  
    80  func (c localCommand) Kill() error {
    81  	return c.cmd.Process.Kill()
    82  }