2013-05-12 17:47:55 -04:00
|
|
|
package rpc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2019-04-03 11:14:55 -04:00
|
|
|
"context"
|
2013-05-12 17:47:55 -04:00
|
|
|
"io"
|
2013-08-23 22:18:15 -04:00
|
|
|
"reflect"
|
2013-05-12 17:47:55 -04:00
|
|
|
"testing"
|
2018-01-22 20:21:10 -05:00
|
|
|
|
|
|
|
"github.com/hashicorp/packer/packer"
|
2020-11-19 18:10:00 -05:00
|
|
|
packersdk "github.com/hashicorp/packer/packer-plugin-sdk/packer"
|
2013-05-12 17:47:55 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestCommunicatorRPC(t *testing.T) {
|
|
|
|
// Create the interface to test
|
2013-08-23 21:29:46 -04:00
|
|
|
c := new(packer.MockCommunicator)
|
2013-05-12 17:47:55 -04:00
|
|
|
|
|
|
|
// Start the server
|
2013-12-10 14:43:02 -05:00
|
|
|
client, server := testClientServer(t)
|
|
|
|
defer client.Close()
|
|
|
|
defer server.Close()
|
|
|
|
server.RegisterCommunicator(c)
|
|
|
|
remote := client.Communicator()
|
2013-06-03 02:08:40 -04:00
|
|
|
|
|
|
|
// The remote command we'll use
|
|
|
|
stdin_r, stdin_w := io.Pipe()
|
|
|
|
stdout_r, stdout_w := io.Pipe()
|
|
|
|
stderr_r, stderr_w := io.Pipe()
|
|
|
|
|
2020-11-19 18:10:00 -05:00
|
|
|
var cmd packersdk.RemoteCmd
|
2013-06-03 02:08:40 -04:00
|
|
|
cmd.Command = "foo"
|
|
|
|
cmd.Stdin = stdin_r
|
|
|
|
cmd.Stdout = stdout_w
|
|
|
|
cmd.Stderr = stderr_w
|
2013-05-12 17:47:55 -04:00
|
|
|
|
2013-08-23 21:29:46 -04:00
|
|
|
// Send some data on stdout and stderr from the mock
|
|
|
|
c.StartStdout = "outfoo\n"
|
|
|
|
c.StartStderr = "errfoo\n"
|
|
|
|
c.StartExitStatus = 42
|
|
|
|
|
2019-04-03 11:14:55 -04:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2013-05-12 17:47:55 -04:00
|
|
|
// Test Start
|
2019-04-03 11:14:55 -04:00
|
|
|
err := remote.Start(ctx, &cmd)
|
2013-08-23 21:29:46 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
2013-05-12 17:47:55 -04:00
|
|
|
|
|
|
|
// Test that we can read from stdout
|
2013-06-03 02:08:40 -04:00
|
|
|
bufOut := bufio.NewReader(stdout_r)
|
2013-05-12 17:47:55 -04:00
|
|
|
data, err := bufOut.ReadString('\n')
|
2013-08-23 21:29:46 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if data != "outfoo\n" {
|
|
|
|
t.Fatalf("bad data: %s", data)
|
|
|
|
}
|
2013-05-12 17:47:55 -04:00
|
|
|
|
|
|
|
// Test that we can read from stderr
|
2013-06-03 02:08:40 -04:00
|
|
|
bufErr := bufio.NewReader(stderr_r)
|
2013-05-12 17:47:55 -04:00
|
|
|
data, err = bufErr.ReadString('\n')
|
2013-08-23 21:29:46 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if data != "errfoo\n" {
|
|
|
|
t.Fatalf("bad data: %s", data)
|
|
|
|
}
|
2013-05-12 17:47:55 -04:00
|
|
|
|
|
|
|
// Test that we can write to stdin
|
2013-08-23 21:29:46 -04:00
|
|
|
stdin_w.Write([]byte("info\n"))
|
|
|
|
stdin_w.Close()
|
|
|
|
cmd.Wait()
|
|
|
|
if c.StartStdin != "info\n" {
|
2013-12-10 14:43:02 -05:00
|
|
|
t.Fatalf("bad data: %s", c.StartStdin)
|
2013-08-23 21:29:46 -04:00
|
|
|
}
|
2013-05-12 19:18:17 -04:00
|
|
|
|
|
|
|
// Test that we can get the exit status properly
|
2019-04-03 11:14:55 -04:00
|
|
|
if cmd.ExitStatus() != 42 {
|
|
|
|
t.Fatalf("bad exit: %d", cmd.ExitStatus())
|
2013-06-03 02:21:55 -04:00
|
|
|
}
|
|
|
|
|
2013-05-12 19:48:46 -04:00
|
|
|
// Test that we can upload things
|
|
|
|
uploadR, uploadW := io.Pipe()
|
2013-08-23 21:29:46 -04:00
|
|
|
go func() {
|
|
|
|
defer uploadW.Close()
|
|
|
|
uploadW.Write([]byte("uploadfoo\n"))
|
|
|
|
}()
|
2014-05-10 00:03:35 -04:00
|
|
|
err = remote.Upload("foo", uploadR, nil)
|
2013-08-23 21:29:46 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !c.UploadCalled {
|
|
|
|
t.Fatal("should have uploaded")
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.UploadPath != "foo" {
|
|
|
|
t.Fatalf("path: %s", c.UploadPath)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.UploadData != "uploadfoo\n" {
|
|
|
|
t.Fatalf("bad: %s", c.UploadData)
|
|
|
|
}
|
2013-05-12 20:09:14 -04:00
|
|
|
|
2013-08-23 22:18:15 -04:00
|
|
|
// Test that we can upload directories
|
|
|
|
dirDst := "foo"
|
|
|
|
dirSrc := "bar"
|
|
|
|
dirExcl := []string{"foo"}
|
|
|
|
err = remote.UploadDir(dirDst, dirSrc, dirExcl)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.UploadDirDst != dirDst {
|
|
|
|
t.Fatalf("bad: %s", c.UploadDirDst)
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.UploadDirSrc != dirSrc {
|
|
|
|
t.Fatalf("bad: %s", c.UploadDirSrc)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(c.UploadDirExclude, dirExcl) {
|
|
|
|
t.Fatalf("bad: %#v", c.UploadDirExclude)
|
|
|
|
}
|
|
|
|
|
2013-05-12 20:09:14 -04:00
|
|
|
// 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
|
|
|
|
2013-05-12 20:09:14 -04:00
|
|
|
go func() {
|
|
|
|
bufDownR := bufio.NewReader(downloadR)
|
|
|
|
downloadData, downloadErr = bufDownR.ReadString('\n')
|
|
|
|
downloadDone <- true
|
|
|
|
}()
|
|
|
|
|
2013-08-23 21:29:46 -04:00
|
|
|
c.DownloadData = "download\n"
|
2013-05-12 20:09:14 -04:00
|
|
|
err = remote.Download("bar", downloadW)
|
2013-08-23 21:29:46 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !c.DownloadCalled {
|
|
|
|
t.Fatal("download should be called")
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.DownloadPath != "bar" {
|
|
|
|
t.Fatalf("bad: %s", c.DownloadPath)
|
|
|
|
}
|
2013-05-12 20:09:14 -04:00
|
|
|
|
|
|
|
<-downloadDone
|
2013-08-23 21:29:46 -04:00
|
|
|
if downloadErr != nil {
|
|
|
|
t.Fatalf("err: %s", downloadErr)
|
|
|
|
}
|
|
|
|
|
|
|
|
if downloadData != "download\n" {
|
|
|
|
t.Fatalf("bad: %s", downloadData)
|
|
|
|
}
|
2013-05-12 17:47:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestCommunicator_ImplementsCommunicator(t *testing.T) {
|
2013-08-23 21:29:46 -04:00
|
|
|
var raw interface{}
|
|
|
|
raw = Communicator(nil)
|
2020-11-19 18:10:00 -05:00
|
|
|
if _, ok := raw.(packersdk.Communicator); !ok {
|
2013-08-23 21:29:46 -04:00
|
|
|
t.Fatal("should be a Communicator")
|
|
|
|
}
|
2013-05-12 17:47:55 -04:00
|
|
|
}
|