Created
April 1, 2019 14:51
-
-
Save notnoop/f6d406021785e34d480695be50961a47 to your computer and use it in GitHub Desktop.
testing command behavior
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"io" | |
"io/ioutil" | |
"os" | |
"os/exec" | |
"sync" | |
"testing" | |
"time" | |
"github.com/stretchr/testify/require" | |
) | |
var testCommandArgs = []string{"-c", "(sleep 80 > /dev/null & ) ; exec sleep 1"} | |
func TestExecStdout_CmdWait(t *testing.T) { | |
cases := []struct { | |
name string | |
stdout io.Writer | |
stderr io.Writer | |
}{ | |
{"plain files", os.Stdout, os.Stderr}, | |
{"discard", ioutil.Discard, ioutil.Discard}, | |
} | |
for _, c := range cases { | |
t.Run(c.name, func(t *testing.T) { | |
cmd := exec.Command("/bin/bash", testCommandArgs...) | |
cmd.Stdout = c.stdout | |
cmd.Stderr = c.stderr | |
err := cmd.Start() | |
if err != nil { | |
t.Fatalf("starting process failed: %v", err) | |
} | |
defer cmd.Process.Kill() | |
start := time.Now() | |
ch := make(chan error) | |
go func() { | |
ch <- cmd.Wait() | |
}() | |
select { | |
case e := <-ch: | |
if err != nil { | |
t.Fatalf("processed exited with an error: %v", e) | |
} | |
case <-time.After(3 * time.Second): | |
t.Fatalf("process didn't exist after timeout: %v", time.Since(start)) | |
} | |
}) | |
} | |
} | |
func TestExecStdout_ProcessWait(t *testing.T) { | |
cases := []struct { | |
name string | |
stdout io.Writer | |
stderr io.Writer | |
}{ | |
{"plain files", os.Stdout, os.Stderr}, | |
{"discard", ioutil.Discard, ioutil.Discard}, | |
} | |
for _, c := range cases { | |
t.Run(c.name, func(t *testing.T) { | |
cmd := exec.Command("/bin/bash", testCommandArgs...) | |
cmd.Stdout = c.stdout | |
cmd.Stderr = c.stderr | |
err := cmd.Start() | |
if err != nil { | |
t.Fatalf("starting process failed: %v", err) | |
} | |
defer cmd.Process.Kill() | |
start := time.Now() | |
ch := make(chan error) | |
go func() { | |
ps, err := cmd.Process.Wait() | |
if err != nil { | |
ch <- err | |
} else if !ps.Success() { | |
ch <- fmt.Errorf("process failed: %v", ps) | |
} | |
ch <- err | |
}() | |
select { | |
case e := <-ch: | |
if err != nil { | |
t.Fatalf("processed exited with an error: %v", e) | |
} | |
case <-time.After(3 * time.Second): | |
t.Fatalf("process didn't exist after timeout: %v", time.Since(start)) | |
} | |
}) | |
} | |
} | |
func TestExecStdout_CmdWait_Piped(t *testing.T) { | |
cases := []struct { | |
name string | |
stdout io.Writer | |
stderr io.Writer | |
}{ | |
{"plain files", os.Stdout, os.Stderr}, | |
{"discard", ioutil.Discard, ioutil.Discard}, | |
} | |
for _, c := range cases { | |
t.Run(c.name, func(t *testing.T) { | |
cmd := exec.Command("/bin/bash", testCommandArgs...) | |
stdoutPipe, err := cmd.StdoutPipe() | |
require.NoError(t, err) | |
stderrPipe, err := cmd.StderrPipe() | |
require.NoError(t, err) | |
err = cmd.Start() | |
if err != nil { | |
t.Fatalf("starting process failed: %v", err) | |
} | |
defer cmd.Process.Kill() | |
start := time.Now() | |
var cgwg sync.WaitGroup | |
cgwg.Add(2) | |
go func() { | |
defer cgwg.Done() | |
io.Copy(c.stdout, stdoutPipe) | |
}() | |
go func() { | |
defer cgwg.Done() | |
io.Copy(c.stderr, stderrPipe) | |
}() | |
//cgwg.Wait() | |
ch := make(chan error) | |
go func() { | |
ch <- cmd.Wait() | |
}() | |
select { | |
case e := <-ch: | |
if err != nil { | |
t.Fatalf("processed exited with an error: %v", e) | |
} | |
case <-time.After(3 * time.Second): | |
t.Fatalf("process didn't exist after timeout: %v", time.Since(start)) | |
} | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment