Skip to content

Instantly share code, notes, and snippets.

@notnoop
Created April 1, 2019 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notnoop/f6d406021785e34d480695be50961a47 to your computer and use it in GitHub Desktop.
Save notnoop/f6d406021785e34d480695be50961a47 to your computer and use it in GitHub Desktop.
testing command behavior
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