示例#1
0
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")
	remote := Communicator(client)

	// The remote command we'll use
	stdin_r, stdin_w := io.Pipe()
	stdout_r, stdout_w := io.Pipe()
	stderr_r, stderr_w := io.Pipe()

	var cmd packer.RemoteCmd
	cmd.Command = "foo"
	cmd.Stdin = stdin_r
	cmd.Stdout = stdout_w
	cmd.Stderr = stderr_w

	// Test Start
	err = remote.Start(&cmd)
	assert.Nil(err, "should not have an error")

	// Test that we can read from stdout
	c.startCmd.Stdout.Write([]byte("outfoo\n"))
	bufOut := bufio.NewReader(stdout_r)
	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
	c.startCmd.Stderr.Write([]byte("errfoo\n"))
	bufErr := bufio.NewReader(stderr_r)
	data, err = bufErr.ReadString('\n')
	assert.Nil(err, "should have no problem reading stderr")
	assert.Equal(data, "errfoo\n", "should be correct stderr")

	// Test that we can write to stdin
	stdin_w.Write([]byte("infoo\n"))
	bufIn := bufio.NewReader(c.startCmd.Stdin)
	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.startCmd.SetExited(42)

	for i := 0; i < 5; i++ {
		cmd.Lock()
		exited := cmd.Exited
		cmd.Unlock()
		if exited {
			assert.Equal(cmd.ExitStatus, 42, "should have proper exit status")
			break
		}

		time.Sleep(50 * time.Millisecond)
	}

	assert.True(cmd.Exited, "should have exited")

	// Test that we can upload things
	uploadR, uploadW := io.Pipe()
	go uploadW.Write([]byte("uploadfoo\n"))
	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

	go func() {
		bufDownR := bufio.NewReader(downloadR)
		downloadData, downloadErr = bufDownR.ReadString('\n')
		downloadDone <- true
	}()

	err = remote.Download("bar", downloadW)
	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")
}