github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/utils/ssh/run_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package ssh_test
     5  
     6  import (
     7  	"io/ioutil"
     8  	"path/filepath"
     9  
    10  	gc "launchpad.net/gocheck"
    11  
    12  	"launchpad.net/juju-core/testing"
    13  	jc "launchpad.net/juju-core/testing/checkers"
    14  	"launchpad.net/juju-core/testing/testbase"
    15  	"launchpad.net/juju-core/utils/ssh"
    16  )
    17  
    18  type ExecuteSSHCommandSuite struct {
    19  	testbase.LoggingSuite
    20  	testbin string
    21  	fakessh string
    22  }
    23  
    24  var _ = gc.Suite(&ExecuteSSHCommandSuite{})
    25  
    26  func (s *ExecuteSSHCommandSuite) SetUpTest(c *gc.C) {
    27  	s.LoggingSuite.SetUpTest(c)
    28  	s.testbin = c.MkDir()
    29  	s.fakessh = filepath.Join(s.testbin, "ssh")
    30  	s.PatchEnvPathPrepend(s.testbin)
    31  }
    32  
    33  func (s *ExecuteSSHCommandSuite) fakeSSH(c *gc.C, cmd string) {
    34  	err := ioutil.WriteFile(s.fakessh, []byte(cmd), 0755)
    35  	c.Assert(err, gc.IsNil)
    36  }
    37  
    38  func (s *ExecuteSSHCommandSuite) TestCaptureOutput(c *gc.C) {
    39  	s.fakeSSH(c, echoSSH)
    40  
    41  	response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
    42  		Host:    "hostname",
    43  		Command: "sudo apt-get update\nsudo apt-get upgrade",
    44  		Timeout: testing.ShortWait,
    45  	})
    46  
    47  	c.Assert(err, gc.IsNil)
    48  	c.Assert(response.Code, gc.Equals, 0)
    49  	c.Assert(string(response.Stdout), gc.Equals, "sudo apt-get update\nsudo apt-get upgrade\n")
    50  	c.Assert(string(response.Stderr), gc.Equals,
    51  		"-o StrictHostKeyChecking no -o PasswordAuthentication no hostname /bin/bash -s\n")
    52  }
    53  
    54  func (s *ExecuteSSHCommandSuite) TestIdentityFile(c *gc.C) {
    55  	s.fakeSSH(c, echoSSH)
    56  
    57  	response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
    58  		IdentityFile: "identity-file",
    59  		Host:         "hostname",
    60  		Timeout:      testing.ShortWait,
    61  	})
    62  
    63  	c.Assert(err, gc.IsNil)
    64  	c.Assert(string(response.Stderr), jc.Contains, " -i identity-file ")
    65  }
    66  
    67  func (s *ExecuteSSHCommandSuite) TestTimoutCaptureOutput(c *gc.C) {
    68  	s.fakeSSH(c, slowSSH)
    69  
    70  	response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
    71  		IdentityFile: "identity-file",
    72  		Host:         "hostname",
    73  		Command:      "ignored",
    74  		Timeout:      testing.ShortWait,
    75  	})
    76  
    77  	c.Check(err, gc.ErrorMatches, "command timed out")
    78  	c.Assert(response.Code, gc.Equals, 0)
    79  	c.Assert(string(response.Stdout), gc.Equals, "stdout\n")
    80  	c.Assert(string(response.Stderr), gc.Equals, "stderr\n")
    81  }
    82  
    83  func (s *ExecuteSSHCommandSuite) TestCapturesReturnCode(c *gc.C) {
    84  	s.fakeSSH(c, passthroughSSH)
    85  
    86  	response, err := ssh.ExecuteCommandOnMachine(ssh.ExecParams{
    87  		IdentityFile: "identity-file",
    88  		Host:         "hostname",
    89  		Command:      "echo stdout; exit 42",
    90  		Timeout:      testing.ShortWait,
    91  	})
    92  
    93  	c.Check(err, gc.IsNil)
    94  	c.Assert(response.Code, gc.Equals, 42)
    95  	c.Assert(string(response.Stdout), gc.Equals, "stdout\n")
    96  	c.Assert(string(response.Stderr), gc.Equals, "")
    97  }
    98  
    99  // echoSSH outputs the command args to stderr, and copies stdin to stdout
   100  var echoSSH = `#!/bin/bash
   101  # Write the args to stderr
   102  echo "$*" >&2
   103  cat /dev/stdin
   104  `
   105  
   106  // slowSSH sleeps for a while after outputting some text to stdout and stderr
   107  var slowSSH = `#!/bin/bash
   108  echo "stderr" >&2
   109  echo "stdout"
   110  sleep 5s
   111  `
   112  
   113  // passthroughSSH creates an ssh that executes stdin.
   114  var passthroughSSH = `#!/bin/bash -s`