Add additional tests for SSH

Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
This commit is contained in:
Nathan LeClaire 2015-12-03 19:45:15 -08:00
parent f17cce330c
commit aa54a5f272
4 changed files with 117 additions and 12 deletions

View File

@ -7,6 +7,14 @@ import (
"github.com/docker/machine/libmachine/state"
)
type errStateInvalidForSSH struct {
HostName string
}
func (e errStateInvalidForSSH) Error() string {
return fmt.Sprintf("Error: Cannot run SSH command: Host %q is not running", e.HostName)
}
func cmdSSH(c CommandLine, api libmachine.API) error {
// Check for help flag -- Needed due to SkipFlagParsing
firstArg := c.Args().First()
@ -31,7 +39,7 @@ func cmdSSH(c CommandLine, api libmachine.API) error {
}
if currentState != state.Running {
return fmt.Errorf("Error: Cannot run SSH command: Host %q is not running", host.Name)
return errStateInvalidForSSH{host.Name}
}
client, err := host.CreateSSHClient()

View File

@ -4,17 +4,36 @@ import (
"testing"
"github.com/docker/machine/commands/commandstest"
"github.com/docker/machine/drivers/fakedriver"
"github.com/docker/machine/libmachine"
"github.com/docker/machine/libmachine/drivers"
"github.com/docker/machine/libmachine/host"
"github.com/docker/machine/libmachine/libmachinetest"
"github.com/docker/machine/libmachine/ssh"
"github.com/docker/machine/libmachine/ssh/sshtest"
"github.com/docker/machine/libmachine/state"
"github.com/stretchr/testify/assert"
)
type FakeSSHClientCreator struct {
client ssh.Client
}
func (fsc *FakeSSHClientCreator) CreateSSHClient(d drivers.Driver) (ssh.Client, error) {
if fsc.client == nil {
fsc.client = &sshtest.FakeClient{}
}
return fsc.client, nil
}
func TestCmdSSH(t *testing.T) {
testCases := []struct {
commandLine CommandLine
api libmachine.API
expectedErr error
helpShown bool
commandLine CommandLine
api libmachine.API
expectedErr error
helpShown bool
clientCreator host.SSHClientCreator
expectedShell []string
}{
{
commandLine: &commandstest.FakeCommandLine{
@ -39,14 +58,54 @@ func TestCmdSSH(t *testing.T) {
api: &libmachinetest.FakeAPI{},
expectedErr: ErrExpectedOneMachine,
},
{
commandLine: &commandstest.FakeCommandLine{
CliArgs: []string{"default", "df", "-h"},
},
api: &libmachinetest.FakeAPI{
Hosts: []*host.Host{
{
Name: "default",
Driver: &fakedriver.Driver{
MockState: state.Running,
},
},
},
},
expectedErr: nil,
clientCreator: &FakeSSHClientCreator{},
expectedShell: []string{"df", "-h"},
},
{
commandLine: &commandstest.FakeCommandLine{
CliArgs: []string{"default"},
},
api: &libmachinetest.FakeAPI{
Hosts: []*host.Host{
{
Name: "default",
Driver: &fakedriver.Driver{
MockState: state.Stopped,
},
},
},
},
expectedErr: errStateInvalidForSSH{"default"},
},
}
for _, tc := range testCases {
host.SetSSHClientCreator(tc.clientCreator)
err := cmdSSH(tc.commandLine, tc.api)
assert.Equal(t, err, tc.expectedErr)
if fcl, ok := tc.commandLine.(*commandstest.FakeCommandLine); ok {
assert.Equal(t, tc.helpShown, fcl.HelpShown)
}
if fcc, ok := tc.clientCreator.(*FakeSSHClientCreator); ok {
assert.Equal(t, tc.expectedShell, fcc.client.(*sshtest.FakeClient).ActivatedShell)
}
}
}

View File

@ -21,10 +21,23 @@ import (
)
var (
validHostNamePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9\-\.]*$`)
errMachineMustBeRunningForUpgrade = errors.New("Error: machine must be running to upgrade.")
validHostNamePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9\-\.]*$`)
errMachineMustBeRunningForUpgrade = errors.New("Error: machine must be running to upgrade.")
stdSSHClientCreator SSHClientCreator = &StandardSSHClientCreator{}
)
type SSHClientCreator interface {
CreateSSHClient(d drivers.Driver) (ssh.Client, error)
}
type StandardSSHClientCreator struct {
drivers.Driver
}
func SetSSHClientCreator(creator SSHClientCreator) {
stdSSHClientCreator = creator
}
type Host struct {
ConfigVersion int
Driver drivers.Driver
@ -58,22 +71,26 @@ func (h *Host) RunSSHCommand(command string) (string, error) {
}
func (h *Host) CreateSSHClient() (ssh.Client, error) {
addr, err := h.Driver.GetSSHHostname()
return stdSSHClientCreator.CreateSSHClient(h.Driver)
}
func (creator *StandardSSHClientCreator) CreateSSHClient(d drivers.Driver) (ssh.Client, error) {
addr, err := d.GetSSHHostname()
if err != nil {
return ssh.ExternalClient{}, err
}
port, err := h.Driver.GetSSHPort()
port, err := d.GetSSHPort()
if err != nil {
return ssh.ExternalClient{}, err
}
auth := &ssh.Auth{}
if h.Driver.GetSSHKeyPath() != "" {
auth.Keys = []string{h.Driver.GetSSHKeyPath()}
if d.GetSSHKeyPath() != "" {
auth.Keys = []string{d.GetSSHKeyPath()}
}
return ssh.NewClient(h.Driver.GetSSHUsername(), addr, port, auth)
return ssh.NewClient(d.GetSSHUsername(), addr, port, auth)
}
func (h *Host) runActionForState(action func() error, desiredState state.State) error {

View File

@ -0,0 +1,21 @@
package sshtest
type CmdResult struct {
Out string
Err error
}
type FakeClient struct {
ActivatedShell []string
Outputs map[string]CmdResult
}
func (fsc *FakeClient) Output(command string) (string, error) {
outerr := fsc.Outputs[command]
return outerr.Out, outerr.Err
}
func (fsc *FakeClient) Shell(args ...string) error {
fsc.ActivatedShell = args
return nil
}