github.com/jerryclinesmith/packer@v0.3.7/packer/rpc/communicator_test.go (about)

     1  package rpc
     2  
     3  import (
     4  	"bufio"
     5  	"github.com/mitchellh/packer/packer"
     6  	"io"
     7  	"net/rpc"
     8  	"reflect"
     9  	"testing"
    10  )
    11  
    12  func TestCommunicatorRPC(t *testing.T) {
    13  	// Create the interface to test
    14  	c := new(packer.MockCommunicator)
    15  
    16  	// Start the server
    17  	server := rpc.NewServer()
    18  	RegisterCommunicator(server, c)
    19  	address := serveSingleConn(server)
    20  
    21  	// Create the client over RPC and run some methods to verify it works
    22  	client, err := rpc.Dial("tcp", address)
    23  	if err != nil {
    24  		t.Fatalf("err: %s", err)
    25  	}
    26  	remote := Communicator(client)
    27  
    28  	// The remote command we'll use
    29  	stdin_r, stdin_w := io.Pipe()
    30  	stdout_r, stdout_w := io.Pipe()
    31  	stderr_r, stderr_w := io.Pipe()
    32  
    33  	var cmd packer.RemoteCmd
    34  	cmd.Command = "foo"
    35  	cmd.Stdin = stdin_r
    36  	cmd.Stdout = stdout_w
    37  	cmd.Stderr = stderr_w
    38  
    39  	// Send some data on stdout and stderr from the mock
    40  	c.StartStdout = "outfoo\n"
    41  	c.StartStderr = "errfoo\n"
    42  	c.StartExitStatus = 42
    43  
    44  	// Test Start
    45  	err = remote.Start(&cmd)
    46  	if err != nil {
    47  		t.Fatalf("err: %s", err)
    48  	}
    49  
    50  	// Test that we can read from stdout
    51  	bufOut := bufio.NewReader(stdout_r)
    52  	data, err := bufOut.ReadString('\n')
    53  	if err != nil {
    54  		t.Fatalf("err: %s", err)
    55  	}
    56  
    57  	if data != "outfoo\n" {
    58  		t.Fatalf("bad data: %s", data)
    59  	}
    60  
    61  	// Test that we can read from stderr
    62  	bufErr := bufio.NewReader(stderr_r)
    63  	data, err = bufErr.ReadString('\n')
    64  	if err != nil {
    65  		t.Fatalf("err: %s", err)
    66  	}
    67  
    68  	if data != "errfoo\n" {
    69  		t.Fatalf("bad data: %s", data)
    70  	}
    71  
    72  	// Test that we can write to stdin
    73  	stdin_w.Write([]byte("info\n"))
    74  	stdin_w.Close()
    75  	cmd.Wait()
    76  	if c.StartStdin != "info\n" {
    77  		t.Fatalf("bad data: %s", data)
    78  	}
    79  
    80  	// Test that we can get the exit status properly
    81  	if cmd.ExitStatus != 42 {
    82  		t.Fatalf("bad exit: %d", cmd.ExitStatus)
    83  	}
    84  
    85  	// Test that we can upload things
    86  	uploadR, uploadW := io.Pipe()
    87  	go func() {
    88  		defer uploadW.Close()
    89  		uploadW.Write([]byte("uploadfoo\n"))
    90  	}()
    91  	err = remote.Upload("foo", uploadR)
    92  	if err != nil {
    93  		t.Fatalf("err: %s", err)
    94  	}
    95  
    96  	if !c.UploadCalled {
    97  		t.Fatal("should have uploaded")
    98  	}
    99  
   100  	if c.UploadPath != "foo" {
   101  		t.Fatalf("path: %s", c.UploadPath)
   102  	}
   103  
   104  	if c.UploadData != "uploadfoo\n" {
   105  		t.Fatalf("bad: %s", c.UploadData)
   106  	}
   107  
   108  	// Test that we can upload directories
   109  	dirDst := "foo"
   110  	dirSrc := "bar"
   111  	dirExcl := []string{"foo"}
   112  	err = remote.UploadDir(dirDst, dirSrc, dirExcl)
   113  	if err != nil {
   114  		t.Fatalf("err: %s", err)
   115  	}
   116  
   117  	if c.UploadDirDst != dirDst {
   118  		t.Fatalf("bad: %s", c.UploadDirDst)
   119  	}
   120  
   121  	if c.UploadDirSrc != dirSrc {
   122  		t.Fatalf("bad: %s", c.UploadDirSrc)
   123  	}
   124  
   125  	if !reflect.DeepEqual(c.UploadDirExclude, dirExcl) {
   126  		t.Fatalf("bad: %#v", c.UploadDirExclude)
   127  	}
   128  
   129  	// Test that we can download things
   130  	downloadR, downloadW := io.Pipe()
   131  	downloadDone := make(chan bool)
   132  	var downloadData string
   133  	var downloadErr error
   134  
   135  	go func() {
   136  		bufDownR := bufio.NewReader(downloadR)
   137  		downloadData, downloadErr = bufDownR.ReadString('\n')
   138  		downloadDone <- true
   139  	}()
   140  
   141  	c.DownloadData = "download\n"
   142  	err = remote.Download("bar", downloadW)
   143  	if err != nil {
   144  		t.Fatalf("err: %s", err)
   145  	}
   146  
   147  	if !c.DownloadCalled {
   148  		t.Fatal("download should be called")
   149  	}
   150  
   151  	if c.DownloadPath != "bar" {
   152  		t.Fatalf("bad: %s", c.DownloadPath)
   153  	}
   154  
   155  	<-downloadDone
   156  	if downloadErr != nil {
   157  		t.Fatalf("err: %s", downloadErr)
   158  	}
   159  
   160  	if downloadData != "download\n" {
   161  		t.Fatalf("bad: %s", downloadData)
   162  	}
   163  }
   164  
   165  func TestCommunicator_ImplementsCommunicator(t *testing.T) {
   166  	var raw interface{}
   167  	raw = Communicator(nil)
   168  	if _, ok := raw.(packer.Communicator); !ok {
   169  		t.Fatal("should be a Communicator")
   170  	}
   171  }