packer: RemoteCommand.ExitChan() and tests
This commit is contained in:
parent
97ba152771
commit
24237da32c
1
TODO.md
1
TODO.md
|
@ -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 {
|
||||||
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 (
|
||||||
"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()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue