github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/packer/rpc/communicator_test.go (about) 1 package rpc 2 3 import ( 4 "bufio" 5 "cgl.tideland.biz/asserts" 6 "github.com/mitchellh/packer/packer" 7 "io" 8 "net/rpc" 9 "testing" 10 "time" 11 ) 12 13 type testCommunicator struct { 14 startCalled bool 15 startCmd *packer.RemoteCmd 16 17 uploadCalled bool 18 uploadPath string 19 uploadData string 20 21 downloadCalled bool 22 downloadPath string 23 } 24 25 func (t *testCommunicator) Start(cmd *packer.RemoteCmd) error { 26 t.startCalled = true 27 t.startCmd = cmd 28 return nil 29 } 30 31 func (t *testCommunicator) Upload(path string, reader io.Reader) (err error) { 32 t.uploadCalled = true 33 t.uploadPath = path 34 t.uploadData, err = bufio.NewReader(reader).ReadString('\n') 35 return 36 } 37 38 func (t *testCommunicator) Download(path string, writer io.Writer) error { 39 t.downloadCalled = true 40 t.downloadPath = path 41 writer.Write([]byte("download\n")) 42 43 return nil 44 } 45 46 func TestCommunicatorRPC(t *testing.T) { 47 assert := asserts.NewTestingAsserts(t, true) 48 49 // Create the interface to test 50 c := new(testCommunicator) 51 52 // Start the server 53 server := rpc.NewServer() 54 RegisterCommunicator(server, c) 55 address := serveSingleConn(server) 56 57 // Create the client over RPC and run some methods to verify it works 58 client, err := rpc.Dial("tcp", address) 59 assert.Nil(err, "should be able to connect") 60 remote := Communicator(client) 61 62 // The remote command we'll use 63 stdin_r, stdin_w := io.Pipe() 64 stdout_r, stdout_w := io.Pipe() 65 stderr_r, stderr_w := io.Pipe() 66 67 var cmd packer.RemoteCmd 68 cmd.Command = "foo" 69 cmd.Stdin = stdin_r 70 cmd.Stdout = stdout_w 71 cmd.Stderr = stderr_w 72 73 // Test Start 74 err = remote.Start(&cmd) 75 assert.Nil(err, "should not have an error") 76 77 // Test that we can read from stdout 78 c.startCmd.Stdout.Write([]byte("outfoo\n")) 79 bufOut := bufio.NewReader(stdout_r) 80 data, err := bufOut.ReadString('\n') 81 assert.Nil(err, "should have no problem reading stdout") 82 assert.Equal(data, "outfoo\n", "should be correct stdout") 83 84 // Test that we can read from stderr 85 c.startCmd.Stderr.Write([]byte("errfoo\n")) 86 bufErr := bufio.NewReader(stderr_r) 87 data, err = bufErr.ReadString('\n') 88 assert.Nil(err, "should have no problem reading stderr") 89 assert.Equal(data, "errfoo\n", "should be correct stderr") 90 91 // Test that we can write to stdin 92 stdin_w.Write([]byte("infoo\n")) 93 bufIn := bufio.NewReader(c.startCmd.Stdin) 94 data, err = bufIn.ReadString('\n') 95 assert.Nil(err, "should have no problem reading stdin") 96 assert.Equal(data, "infoo\n", "should be correct stdin") 97 98 // Test that we can get the exit status properly 99 c.startCmd.SetExited(42) 100 101 for i := 0; i < 5; i++ { 102 if cmd.Exited { 103 assert.Equal(cmd.ExitStatus, 42, "should have proper exit status") 104 break 105 } 106 107 time.Sleep(50 * time.Millisecond) 108 } 109 110 assert.True(cmd.Exited, "should have exited") 111 112 // Test that we can upload things 113 uploadR, uploadW := io.Pipe() 114 go uploadW.Write([]byte("uploadfoo\n")) 115 err = remote.Upload("foo", uploadR) 116 assert.Nil(err, "should not error") 117 assert.True(c.uploadCalled, "should be called") 118 assert.Equal(c.uploadPath, "foo", "should be correct path") 119 assert.Equal(c.uploadData, "uploadfoo\n", "should have the proper data") 120 121 // Test that we can download things 122 downloadR, downloadW := io.Pipe() 123 downloadDone := make(chan bool) 124 var downloadData string 125 var downloadErr error 126 127 go func() { 128 bufDownR := bufio.NewReader(downloadR) 129 downloadData, downloadErr = bufDownR.ReadString('\n') 130 downloadDone <- true 131 }() 132 133 err = remote.Download("bar", downloadW) 134 assert.Nil(err, "should not error") 135 assert.True(c.downloadCalled, "should have called download") 136 assert.Equal(c.downloadPath, "bar", "should have correct download path") 137 138 <-downloadDone 139 assert.Nil(downloadErr, "should not error reading download data") 140 assert.Equal(downloadData, "download\n", "should have the proper data") 141 } 142 143 func TestCommunicator_ImplementsCommunicator(t *testing.T) { 144 assert := asserts.NewTestingAsserts(t, true) 145 146 var r packer.Communicator 147 c := Communicator(nil) 148 149 assert.Implementor(c, &r, "should be a Communicator") 150 }