Move towards using external binaries / RPC plugins
- First RPC steps - Work on some flaws in RPC model - Remove unused TLS settings from Engine and Swarm options - Add code to correctly encode data over the network - Add client driver for RPC - Rename server driver file - Start to make marshal make sense - Fix silly RPC method args and add client - Fix some issues with RPC calls, and marshaling - Simplify plugin main.go - Move towards 100% plugin in CLI - Ensure that plugin servers are cleaned up properly - Make flag parsing for driver flags work properly Includes some work carried from @dmp42 updating the build process and tests to use the new method. Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
This commit is contained in:
155
libmachine/drivers/plugin/localbinary/plugin_test.go
Normal file
155
libmachine/drivers/plugin/localbinary/plugin_test.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package localbinary
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/machine/libmachine/log"
|
||||
)
|
||||
|
||||
type FakeExecutor struct {
|
||||
stdout, stderr io.ReadCloser
|
||||
closed bool
|
||||
}
|
||||
|
||||
func (fe *FakeExecutor) Start() (*bufio.Scanner, *bufio.Scanner, error) {
|
||||
return bufio.NewScanner(fe.stdout), bufio.NewScanner(fe.stderr), nil
|
||||
}
|
||||
|
||||
func (fe *FakeExecutor) Close() error {
|
||||
fe.closed = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestLocalBinaryPluginAddress(t *testing.T) {
|
||||
lbp := &LocalBinaryPlugin{}
|
||||
expectedAddr := "127.0.0.1:12345"
|
||||
|
||||
lbp.addrCh = make(chan string, 1)
|
||||
lbp.addrCh <- expectedAddr
|
||||
|
||||
// Call the first time to read from the channel
|
||||
addr, err := lbp.Address()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, instead got %s", err)
|
||||
}
|
||||
if addr != expectedAddr {
|
||||
t.Fatal("Expected did not match actual address")
|
||||
}
|
||||
|
||||
// Call the second time to read the "cached" address value
|
||||
addr, err = lbp.Address()
|
||||
if err != nil {
|
||||
t.Fatalf("Expected no error, instead got %s", err)
|
||||
}
|
||||
if addr != expectedAddr {
|
||||
t.Fatal("Expected did not match actual address")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalBinaryPluginAddressTimeout(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping timeout test")
|
||||
}
|
||||
lbp := &LocalBinaryPlugin{}
|
||||
lbp.addrCh = make(chan string, 1)
|
||||
go func() {
|
||||
_, err := lbp.Address()
|
||||
if err == nil {
|
||||
t.Fatalf("Expected to get a timeout error, instead got %s", err)
|
||||
}
|
||||
}()
|
||||
time.Sleep(defaultTimeout + 1)
|
||||
}
|
||||
|
||||
func TestLocalBinaryPluginClose(t *testing.T) {
|
||||
lbp := &LocalBinaryPlugin{}
|
||||
lbp.stopCh = make(chan bool, 1)
|
||||
go lbp.Close()
|
||||
stopped := <-lbp.stopCh
|
||||
if !stopped {
|
||||
t.Fatal("Close did not send a stop message on the proper channel")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecServer(t *testing.T) {
|
||||
log.IsDebug = true
|
||||
machineName := "test"
|
||||
|
||||
logReader, logWriter := io.Pipe()
|
||||
|
||||
log.SetOutWriter(logWriter)
|
||||
log.SetErrWriter(logWriter)
|
||||
|
||||
defer func() {
|
||||
log.IsDebug = false
|
||||
log.SetOutWriter(os.Stdout)
|
||||
log.SetErrWriter(os.Stderr)
|
||||
}()
|
||||
|
||||
stdoutReader, stdoutWriter := io.Pipe()
|
||||
stderrReader, stderrWriter := io.Pipe()
|
||||
|
||||
fe := &FakeExecutor{
|
||||
stdout: stdoutReader,
|
||||
stderr: stderrReader,
|
||||
}
|
||||
|
||||
lbp := &LocalBinaryPlugin{
|
||||
MachineName: machineName,
|
||||
Executor: fe,
|
||||
addrCh: make(chan string, 1),
|
||||
stopCh: make(chan bool, 1),
|
||||
}
|
||||
|
||||
finalErr := make(chan error, 1)
|
||||
|
||||
// Start the docker-machine-foo plugin server
|
||||
go func() {
|
||||
finalErr <- lbp.execServer()
|
||||
}()
|
||||
|
||||
expectedAddr := "127.0.0.1:12345"
|
||||
expectedPluginOut := "Doing some fun plugin stuff..."
|
||||
expectedPluginErr := "Uh oh, something in plugin went wrong..."
|
||||
|
||||
logScanner := bufio.NewScanner(logReader)
|
||||
|
||||
if _, err := io.WriteString(stdoutWriter, expectedAddr+"\n"); err != nil {
|
||||
t.Fatalf("Error attempting to write plugin address: %s", err)
|
||||
}
|
||||
|
||||
if addr := <-lbp.addrCh; addr != expectedAddr {
|
||||
t.Fatalf("Expected to read the expected address properly in server but did not")
|
||||
}
|
||||
|
||||
expectedOut := fmt.Sprintf("%s%s", fmt.Sprintf(pluginOutPrefix, machineName), expectedPluginOut)
|
||||
|
||||
if _, err := io.WriteString(stdoutWriter, expectedPluginOut+"\n"); err != nil {
|
||||
t.Fatalf("Error attempting to write to out in plugin: %s", err)
|
||||
}
|
||||
|
||||
if logScanner.Scan(); logScanner.Text() != expectedOut {
|
||||
t.Fatalf("Output written to log was not what we expected\nexpected: %s\nactual: %s", expectedOut, logScanner.Text())
|
||||
}
|
||||
|
||||
expectedErr := fmt.Sprintf("%s%s", fmt.Sprintf(pluginErrPrefix, machineName), expectedPluginErr)
|
||||
|
||||
if _, err := io.WriteString(stderrWriter, expectedPluginErr+"\n"); err != nil {
|
||||
t.Fatalf("Error attempting to write to err in plugin: %s", err)
|
||||
}
|
||||
|
||||
if logScanner.Scan(); logScanner.Text() != expectedErr {
|
||||
t.Fatalf("Error written to log was not what we expected\nexpected: %s\nactual: %s", expectedErr, logScanner.Text())
|
||||
}
|
||||
|
||||
lbp.Close()
|
||||
|
||||
if err := <-finalErr; err != nil {
|
||||
t.Fatalf("Error serving: %s", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user