123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- /*
- Copyright 2017 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package testingexec
- import (
- "context"
- "fmt"
- "io"
- "k8s.io/utils/exec"
- )
- // FakeExec is a simple scripted Interface type.
- type FakeExec struct {
- CommandScript []FakeCommandAction
- CommandCalls int
- LookPathFunc func(string) (string, error)
- }
- var _ exec.Interface = &FakeExec{}
- // FakeCommandAction is the function to be executed
- type FakeCommandAction func(cmd string, args ...string) exec.Cmd
- // Command is to track the commands that are executed
- func (fake *FakeExec) Command(cmd string, args ...string) exec.Cmd {
- if fake.CommandCalls > len(fake.CommandScript)-1 {
- panic(fmt.Sprintf("ran out of Command() actions. Could not handle command [%d]: %s args: %v", fake.CommandCalls, cmd, args))
- }
- i := fake.CommandCalls
- fake.CommandCalls++
- return fake.CommandScript[i](cmd, args...)
- }
- // CommandContext wraps arguments into exec.Cmd
- func (fake *FakeExec) CommandContext(ctx context.Context, cmd string, args ...string) exec.Cmd {
- return fake.Command(cmd, args...)
- }
- // LookPath is for finding the path of a file
- func (fake *FakeExec) LookPath(file string) (string, error) {
- return fake.LookPathFunc(file)
- }
- // FakeCmd is a simple scripted Cmd type.
- type FakeCmd struct {
- Argv []string
- CombinedOutputScript []FakeCombinedOutputAction
- CombinedOutputCalls int
- CombinedOutputLog [][]string
- RunScript []FakeRunAction
- RunCalls int
- RunLog [][]string
- Dirs []string
- Stdin io.Reader
- Stdout io.Writer
- Stderr io.Writer
- Env []string
- StdoutPipeResponse FakeStdIOPipeResponse
- StderrPipeResponse FakeStdIOPipeResponse
- WaitResponse error
- StartResponse error
- }
- var _ exec.Cmd = &FakeCmd{}
- // InitFakeCmd is for creating a fake exec.Cmd
- func InitFakeCmd(fake *FakeCmd, cmd string, args ...string) exec.Cmd {
- fake.Argv = append([]string{cmd}, args...)
- return fake
- }
- // FakeStdIOPipeResponse holds responses to use as fakes for the StdoutPipe and
- // StderrPipe method calls
- type FakeStdIOPipeResponse struct {
- ReadCloser io.ReadCloser
- Error error
- }
- // FakeCombinedOutputAction is a function type
- type FakeCombinedOutputAction func() ([]byte, error)
- // FakeRunAction is a function type
- type FakeRunAction func() ([]byte, []byte, error)
- // SetDir sets the directory
- func (fake *FakeCmd) SetDir(dir string) {
- fake.Dirs = append(fake.Dirs, dir)
- }
- // SetStdin sets the stdin
- func (fake *FakeCmd) SetStdin(in io.Reader) {
- fake.Stdin = in
- }
- // SetStdout sets the stdout
- func (fake *FakeCmd) SetStdout(out io.Writer) {
- fake.Stdout = out
- }
- // SetStderr sets the stderr
- func (fake *FakeCmd) SetStderr(out io.Writer) {
- fake.Stderr = out
- }
- // SetEnv sets the environment variables
- func (fake *FakeCmd) SetEnv(env []string) {
- fake.Env = env
- }
- // StdoutPipe returns an injected ReadCloser & error (via StdoutPipeResponse)
- // to be able to inject an output stream on Stdout
- func (fake *FakeCmd) StdoutPipe() (io.ReadCloser, error) {
- return fake.StdoutPipeResponse.ReadCloser, fake.StdoutPipeResponse.Error
- }
- // StderrPipe returns an injected ReadCloser & error (via StderrPipeResponse)
- // to be able to inject an output stream on Stderr
- func (fake *FakeCmd) StderrPipe() (io.ReadCloser, error) {
- return fake.StderrPipeResponse.ReadCloser, fake.StderrPipeResponse.Error
- }
- // Start mimicks starting the process (in the background) and returns the
- // injected StartResponse
- func (fake *FakeCmd) Start() error {
- return fake.StartResponse
- }
- // Wait mimicks waiting for the process to exit returns the
- // injected WaitResponse
- func (fake *FakeCmd) Wait() error {
- return fake.WaitResponse
- }
- // Run sets runs the command
- func (fake *FakeCmd) Run() error {
- if fake.RunCalls > len(fake.RunScript)-1 {
- panic("ran out of Run() actions")
- }
- if fake.RunLog == nil {
- fake.RunLog = [][]string{}
- }
- i := fake.RunCalls
- fake.RunLog = append(fake.RunLog, append([]string{}, fake.Argv...))
- fake.RunCalls++
- stdout, stderr, err := fake.RunScript[i]()
- if stdout != nil {
- fake.Stdout.Write(stdout)
- }
- if stderr != nil {
- fake.Stderr.Write(stderr)
- }
- return err
- }
- // CombinedOutput returns the output from the command
- func (fake *FakeCmd) CombinedOutput() ([]byte, error) {
- if fake.CombinedOutputCalls > len(fake.CombinedOutputScript)-1 {
- panic("ran out of CombinedOutput() actions")
- }
- if fake.CombinedOutputLog == nil {
- fake.CombinedOutputLog = [][]string{}
- }
- i := fake.CombinedOutputCalls
- fake.CombinedOutputLog = append(fake.CombinedOutputLog, append([]string{}, fake.Argv...))
- fake.CombinedOutputCalls++
- return fake.CombinedOutputScript[i]()
- }
- // Output is the response from the command
- func (fake *FakeCmd) Output() ([]byte, error) {
- return nil, fmt.Errorf("unimplemented")
- }
- // Stop is to stop the process
- func (fake *FakeCmd) Stop() {
- // no-op
- }
- // FakeExitError is a simple fake ExitError type.
- type FakeExitError struct {
- Status int
- }
- var _ exec.ExitError = FakeExitError{}
- func (fake FakeExitError) String() string {
- return fmt.Sprintf("exit %d", fake.Status)
- }
- func (fake FakeExitError) Error() string {
- return fake.String()
- }
- // Exited always returns true
- func (fake FakeExitError) Exited() bool {
- return true
- }
- // ExitStatus returns the fake status
- func (fake FakeExitError) ExitStatus() int {
- return fake.Status
- }
|