packer-cn/packer/rpc/communicator_test.go

156 lines
4.0 KiB
Go
Raw Normal View History

2013-05-12 17:47:55 -04:00
package rpc
import (
"bufio"
"cgl.tideland.biz/asserts"
"github.com/mitchellh/packer/packer"
"io"
"net/rpc"
"testing"
)
type testCommunicator struct {
startCalled bool
2013-05-20 19:50:35 -04:00
startCmd string
2013-05-12 17:47:55 -04:00
2013-05-20 19:50:35 -04:00
startIn *io.PipeReader
startOut *io.PipeWriter
startErr *io.PipeWriter
startExited *bool
startExitStatus *int
2013-05-12 19:48:46 -04:00
uploadCalled bool
2013-05-20 19:50:35 -04:00
uploadPath string
uploadData string
downloadCalled bool
2013-05-20 19:50:35 -04:00
downloadPath string
2013-05-12 17:47:55 -04:00
}
func (t *testCommunicator) Start(cmd string) (*packer.RemoteCommand, error) {
t.startCalled = true
t.startCmd = cmd
var stdin *io.PipeWriter
var stdout, stderr *io.PipeReader
t.startIn, stdin = io.Pipe()
stdout, t.startOut = io.Pipe()
stderr, t.startErr = io.Pipe()
rc := &packer.RemoteCommand{
Stdin: stdin,
Stdout: stdout,
Stderr: stderr,
Exited: false,
2013-06-01 20:48:19 -04:00
ExitStatus: 0,
2013-05-12 17:47:55 -04:00
}
t.startExited = &rc.Exited
t.startExitStatus = &rc.ExitStatus
2013-05-12 17:47:55 -04:00
return rc, nil
}
func (t *testCommunicator) Upload(path string, reader io.Reader) (err error) {
2013-05-12 19:48:46 -04:00
t.uploadCalled = true
t.uploadPath = path
t.uploadData, err = bufio.NewReader(reader).ReadString('\n')
return
}
2013-05-12 17:47:55 -04:00
func (t *testCommunicator) Download(path string, writer io.Writer) error {
t.downloadCalled = true
t.downloadPath = path
writer.Write([]byte("download\n"))
return nil
}
2013-05-12 17:47:55 -04:00
func TestCommunicatorRPC(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
// Create the interface to test
c := new(testCommunicator)
// Start the server
server := rpc.NewServer()
RegisterCommunicator(server, c)
address := serveSingleConn(server)
// Create the client over RPC and run some methods to verify it works
client, err := rpc.Dial("tcp", address)
assert.Nil(err, "should be able to connect")
// Test Start
remote := Communicator(client)
rc, err := remote.Start("foo")
assert.Nil(err, "should not have an error")
// Test that we can read from stdout
bufOut := bufio.NewReader(rc.Stdout)
c.startOut.Write([]byte("outfoo\n"))
data, err := bufOut.ReadString('\n')
assert.Nil(err, "should have no problem reading stdout")
assert.Equal(data, "outfoo\n", "should be correct stdout")
// Test that we can read from stderr
bufErr := bufio.NewReader(rc.Stderr)
c.startErr.Write([]byte("errfoo\n"))
data, err = bufErr.ReadString('\n')
assert.Nil(err, "should have no problem reading stdout")
assert.Equal(data, "errfoo\n", "should be correct stdout")
// Test that we can write to stdin
bufIn := bufio.NewReader(c.startIn)
rc.Stdin.Write([]byte("infoo\n"))
data, err = bufIn.ReadString('\n')
assert.Nil(err, "should have no problem reading stdin")
assert.Equal(data, "infoo\n", "should be correct stdin")
// Test that we can get the exit status properly
*c.startExitStatus = 42
*c.startExited = true
rc.Wait()
assert.Equal(rc.ExitStatus, 42, "should have proper exit status")
2013-05-12 19:48:46 -04:00
// Test that we can upload things
uploadR, uploadW := io.Pipe()
go uploadW.Write([]byte("uploadfoo\n"))
2013-05-12 19:48:46 -04:00
err = remote.Upload("foo", uploadR)
assert.Nil(err, "should not error")
assert.True(c.uploadCalled, "should be called")
assert.Equal(c.uploadPath, "foo", "should be correct path")
assert.Equal(c.uploadData, "uploadfoo\n", "should have the proper data")
// Test that we can download things
downloadR, downloadW := io.Pipe()
downloadDone := make(chan bool)
var downloadData string
var downloadErr error
2013-05-12 19:48:46 -04:00
go func() {
bufDownR := bufio.NewReader(downloadR)
downloadData, downloadErr = bufDownR.ReadString('\n')
downloadDone <- true
}()
err = remote.Download("bar", downloadW)
2013-05-12 19:48:46 -04:00
assert.Nil(err, "should not error")
assert.True(c.downloadCalled, "should have called download")
assert.Equal(c.downloadPath, "bar", "should have correct download path")
<-downloadDone
assert.Nil(downloadErr, "should not error reading download data")
assert.Equal(downloadData, "download\n", "should have the proper data")
2013-05-12 17:47:55 -04:00
}
func TestCommunicator_ImplementsCommunicator(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
2013-05-12 17:47:55 -04:00
var r packer.Communicator
c := Communicator(nil)
2013-05-12 17:47:55 -04:00
assert.Implementor(c, &r, "should be a Communicator")
2013-05-12 17:47:55 -04:00
}