Commit 24237da3 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer: RemoteCommand.ExitChan() and tests

parent 97ba1527
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* communicator/ssh: Ability to re-establish connection * communicator/ssh: Ability to re-establish connection
* communicator/ssh: Download() * communicator/ssh: Download()
* packer: Communicator should have Close() method * packer: Communicator should have Close() method
* packer: RemoteCommand.ExitChan() should be more efficient
* packer: Ui input * packer: Ui input
* packer/plugin: Better error messages/detection if plugin crashes * packer/plugin: Better error messages/detection if plugin crashes
* packer/plugin: Testing of client struct/methods * packer/plugin: Testing of client struct/methods
......
...@@ -36,6 +36,32 @@ type RemoteCommand struct { ...@@ -36,6 +36,32 @@ type RemoteCommand struct {
ExitStatus int ExitStatus int
} }
// StdoutStream returns a channel that will be sent all the output
// of stdout as it comes. The output isn't guaranteed to be a full line.
// When the channel is closed, the process is exited.
func (r *RemoteCommand) StdoutChan() (<-chan string) {
return nil
}
// ExitChan returns a channel that will be sent the exit status once
// the process exits. This can be used in cases such a select statement
// waiting on the process to end.
func (r *RemoteCommand) ExitChan() (<-chan int) {
// TODO(mitchellh): lock
// TODO(mitchellh): Something more efficient than multiple Wait() calls
// Make a single buffered channel so that the send doesn't block.
exitChan := make(chan int, 1)
go func() {
defer close(exitChan)
r.Wait()
exitChan <- r.ExitStatus
}()
return exitChan
}
// Wait waits for the command to exit. // Wait waits for the command to exit.
func (r *RemoteCommand) Wait() { func (r *RemoteCommand) Wait() {
// Busy wait on being exited. We put a sleep to be kind to the // Busy wait on being exited. We put a sleep to be kind to the
......
...@@ -5,6 +5,31 @@ import ( ...@@ -5,6 +5,31 @@ import (
"time" "time"
) )
func TestRemoteCommand_ExitChan(t *testing.T) {
t.Parallel()
rc := &RemoteCommand{}
exitChan := rc.ExitChan()
// Set the exit data so that it is sent
rc.ExitStatus = 42
rc.Exited = true
select {
case exitCode := <-exitChan:
if exitCode != 42 {
t.Fatal("invalid exit code")
}
_, ok := <-exitChan
if ok {
t.Fatal("exit channel should be closed")
}
case <-time.After(500 * time.Millisecond):
t.Fatal("exit channel never sent")
}
}
func TestRemoteCommand_WaitBlocks(t *testing.T) { func TestRemoteCommand_WaitBlocks(t *testing.T) {
t.Parallel() t.Parallel()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment