parent
2a90ce6178
commit
eadb40da91
|
@ -5,6 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ func (c *MockCommunicator) Start(ctx context.Context, rc *RemoteCmd) error {
|
||||||
if rc.Stdout != nil && c.StartStdout != "" {
|
if rc.Stdout != nil && c.StartStdout != "" {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
rc.Stdout.Write([]byte(c.StartStdout))
|
io.Copy(rc.Stdout, strings.NewReader(c.StartStdout))
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -52,7 +53,7 @@ func (c *MockCommunicator) Start(ctx context.Context, rc *RemoteCmd) error {
|
||||||
if rc.Stderr != nil && c.StartStderr != "" {
|
if rc.Stderr != nil && c.StartStderr != "" {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
rc.Stderr.Write([]byte(c.StartStderr))
|
io.Copy(rc.Stderr, strings.NewReader(c.StartStderr))
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,48 +3,69 @@ package packer
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/mitchellh/iochan"
|
||||||
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRemoteCmd_StartWithUi(t *testing.T) {
|
func TestRemoteCmd_StartWithUi(t *testing.T) {
|
||||||
data := "hello\nworld\nthere"
|
data := []string{
|
||||||
|
"hello",
|
||||||
|
"world",
|
||||||
|
"foo",
|
||||||
|
"there",
|
||||||
|
}
|
||||||
|
|
||||||
originalOutput := new(bytes.Buffer)
|
originalOutputReader, originalOutputWriter := io.Pipe()
|
||||||
uiOutput := new(bytes.Buffer)
|
uilOutputReader, uilOutputWriter := io.Pipe()
|
||||||
|
|
||||||
testComm := new(MockCommunicator)
|
testComm := new(MockCommunicator)
|
||||||
testComm.StartStdout = data
|
testComm.StartStdout = strings.Join(data, "\n") + "\n"
|
||||||
testUi := &BasicUi{
|
testUi := &BasicUi{
|
||||||
Reader: new(bytes.Buffer),
|
Reader: new(bytes.Buffer),
|
||||||
Writer: uiOutput,
|
Writer: uilOutputWriter,
|
||||||
}
|
}
|
||||||
|
|
||||||
rc := &RemoteCmd{
|
rc := &RemoteCmd{
|
||||||
Command: "test",
|
Command: "test",
|
||||||
Stdout: originalOutput,
|
Stdout: originalOutputWriter,
|
||||||
}
|
}
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
wg := errgroup.Group{}
|
||||||
|
|
||||||
|
testPrintFn := func(in io.Reader, expected []string) error {
|
||||||
|
i := 0
|
||||||
|
got := []string{}
|
||||||
|
for output := range iochan.LineReader(in) {
|
||||||
|
got = append(got, output)
|
||||||
|
i++
|
||||||
|
if i == len(expected) {
|
||||||
|
// here ideally the LineReader chan should be closed, but since
|
||||||
|
// the stream virtually has no ending we need to leave early.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if diff := cmp.Diff(got, expected); diff != "" {
|
||||||
|
t.Fatalf("bad output: %s", diff)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Go(func() error { return testPrintFn(uilOutputReader, data) })
|
||||||
|
wg.Go(func() error { return testPrintFn(originalOutputReader, data) })
|
||||||
|
|
||||||
err := rc.RunWithUi(ctx, testComm, testUi)
|
err := rc.RunWithUi(ctx, testComm, testUi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sometimes cmd has returned and everything can be printed later on
|
wg.Wait()
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
|
|
||||||
expected := strings.TrimSpace(data)
|
|
||||||
if diff := cmp.Diff(strings.TrimSpace(uiOutput.String()), expected); diff != "" {
|
|
||||||
t.Fatalf("bad output: %s", diff)
|
|
||||||
}
|
|
||||||
|
|
||||||
if originalOutput.String() != expected {
|
|
||||||
t.Fatalf("bad: %#v", originalOutput.String())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoteCmd_Wait(t *testing.T) {
|
func TestRemoteCmd_Wait(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue