1
// Copyright 2013 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
13
"github.com/juju/testing"
14
jc "github.com/juju/testing/checkers"
15
gc "gopkg.in/check.v1"
17
"github.com/juju/utils/ssh"
21
shortWait = 50 * time.Millisecond
22
longWait = 10 * time.Second
25
type ExecuteSSHCommandSuite struct {
26
testing.IsolationSuite
32
var _ = gc.Suite(&ExecuteSSHCommandSuite{})
34
func (s *ExecuteSSHCommandSuite) SetUpSuite(c *gc.C) {
35
s.originalPath = os.Getenv("PATH")
36
s.IsolationSuite.SetUpSuite(c)
39
func (s *ExecuteSSHCommandSuite) SetUpTest(c *gc.C) {
40
if runtime.GOOS == "windows" {
41
c.Skip("issue 1403084: Tests use OpenSSH only")
43
s.IsolationSuite.SetUpTest(c)
44
err := os.Setenv("PATH", s.originalPath)
45
c.Assert(err, jc.ErrorIsNil)
47
s.fakessh = filepath.Join(s.testbin, "ssh")
48
s.PatchEnvPathPrepend(s.testbin)
51
func (s *ExecuteSSHCommandSuite) fakeSSH(c *gc.C, cmd string) {
52
err := ioutil.WriteFile(s.fakessh, []byte(cmd), 0755)
53
c.Assert(err, jc.ErrorIsNil)
56
func (s *ExecuteSSHCommandSuite) TestCaptureOutput(c *gc.C) {
59
response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
61
Command: "sudo apt-get update\nsudo apt-get upgrade",
65
c.Assert(err, jc.ErrorIsNil)
66
c.Assert(response.Code, gc.Equals, 0)
67
c.Assert(string(response.Stdout), gc.Equals, "sudo apt-get update\nsudo apt-get upgrade\n")
68
c.Assert(string(response.Stderr), gc.Equals,
69
"-o StrictHostKeyChecking no -o PasswordAuthentication no -o ServerAliveInterval 30 hostname /bin/bash -s\n")
72
func (s *ExecuteSSHCommandSuite) TestIdentityFile(c *gc.C) {
75
response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
76
IdentityFile: "identity-file",
81
c.Assert(err, jc.ErrorIsNil)
82
c.Assert(string(response.Stderr), jc.Contains, " -i identity-file ")
85
func (s *ExecuteSSHCommandSuite) TestTimoutCaptureOutput(c *gc.C) {
88
response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
89
IdentityFile: "identity-file",
95
c.Check(err, gc.ErrorMatches, "command timed out")
96
c.Assert(response.Code, gc.Equals, 0)
97
c.Assert(string(response.Stdout), gc.Equals, "stdout\n")
98
c.Assert(string(response.Stderr), gc.Equals, "stderr\n")
101
func (s *ExecuteSSHCommandSuite) TestCapturesReturnCode(c *gc.C) {
102
s.fakeSSH(c, passthroughSSH)
104
response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
105
IdentityFile: "identity-file",
107
Command: "echo stdout; exit 42",
111
c.Check(err, jc.ErrorIsNil)
112
c.Assert(response.Code, gc.Equals, 42)
113
c.Assert(string(response.Stdout), gc.Equals, "stdout\n")
114
c.Assert(string(response.Stderr), gc.Equals, "")
117
// echoSSH outputs the command args to stderr, and copies stdin to stdout
118
var echoSSH = `#!/bin/bash
119
# Write the args to stderr
124
// slowSSH sleeps for a while after outputting some text to stdout and stderr
125
var slowSSH = `#!/bin/bash
131
// passthroughSSH creates an ssh that executes stdin.
132
var passthroughSSH = `#!/bin/bash -s`