github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/commands/scp_unix_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // +build !windows
     5  
     6  package commands
     7  
     8  import (
     9  	"io/ioutil"
    10  	"path/filepath"
    11  
    12  	"github.com/juju/cmd/cmdtesting"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	jujussh "github.com/juju/juju/network/ssh"
    17  )
    18  
    19  var _ = gc.Suite(&SCPSuite{})
    20  
    21  type SCPSuite struct {
    22  	SSHCommonSuite
    23  }
    24  
    25  var scpTests = []struct {
    26  	about       string
    27  	args        []string
    28  	hostChecker jujussh.ReachableChecker
    29  	forceAPIv1  bool
    30  	expected    argsSpec
    31  	error       string
    32  }{
    33  	{
    34  		about:       "scp from machine 0 to current dir (api v1)",
    35  		args:        []string{"0:foo", "."},
    36  		hostChecker: validAddresses("0.private", "0.public"),
    37  		forceAPIv1:  true,
    38  		expected: argsSpec{
    39  			args:            "ubuntu@0.public:foo .",
    40  			hostKeyChecking: "yes",
    41  			knownHosts:      "0",
    42  		},
    43  	}, {
    44  		about:       "scp from machine 0 to current dir (api v2)",
    45  		args:        []string{"0:foo", "."},
    46  		hostChecker: validAddresses("0.private", "0.public", "0.1.2.3"), // set by setAddresses() and setLinkLayerDevicesAddresses()
    47  		forceAPIv1:  false,
    48  		expected: argsSpec{
    49  			argsMatch:       `ubuntu@0.(public|private|1\.2\.3):foo \.`, // can be any of the 3
    50  			hostKeyChecking: "yes",
    51  			knownHosts:      "0",
    52  		},
    53  	}, {
    54  		about:       "scp from machine 0 to current dir with extra args",
    55  		args:        []string{"0:foo", ".", "-rv", "-o", "SomeOption"},
    56  		hostChecker: validAddresses("0.public"),
    57  		expected: argsSpec{
    58  			args:            "ubuntu@0.public:foo . -rv -o SomeOption",
    59  			hostKeyChecking: "yes",
    60  			knownHosts:      "0",
    61  		},
    62  	}, {
    63  		about:       "scp from current dir to machine 0",
    64  		args:        []string{"foo", "0:"},
    65  		hostChecker: validAddresses("0.public"),
    66  		expected: argsSpec{
    67  			args:            "foo ubuntu@0.public:",
    68  			hostKeyChecking: "yes",
    69  			knownHosts:      "0",
    70  		},
    71  	}, {
    72  		about:       "scp when no keys available",
    73  		args:        []string{"foo", "1:"},
    74  		hostChecker: validAddresses("1.public"),
    75  		error:       `retrieving SSH host keys for "1": keys not found`,
    76  	}, {
    77  		about:       "scp when no keys available, with --no-host-key-checks",
    78  		args:        []string{"--no-host-key-checks", "foo", "1:"},
    79  		hostChecker: validAddresses("1.public"),
    80  		expected: argsSpec{
    81  			args:            "foo ubuntu@1.public:",
    82  			hostKeyChecking: "no",
    83  			knownHosts:      "null",
    84  		},
    85  	}, {
    86  		about:       "scp from current dir to machine 0 with extra args",
    87  		args:        []string{"foo", "0:", "-r", "-v"},
    88  		hostChecker: validAddresses("0.public"),
    89  		expected: argsSpec{
    90  			args:            "foo ubuntu@0.public: -r -v",
    91  			hostKeyChecking: "yes",
    92  			knownHosts:      "0",
    93  		},
    94  	}, {
    95  		about:       "scp from machine 0 to unit mysql/0",
    96  		args:        []string{"0:foo", "mysql/0:/foo"},
    97  		hostChecker: validAddresses("0.public"),
    98  		expected: argsSpec{
    99  			args:            "ubuntu@0.public:foo ubuntu@0.public:/foo",
   100  			hostKeyChecking: "yes",
   101  			knownHosts:      "0",
   102  		},
   103  	}, {
   104  		about:       "scp from machine 0 to unit mysql/0 and extra args",
   105  		args:        []string{"0:foo", "mysql/0:/foo", "-q"},
   106  		hostChecker: validAddresses("0.public"),
   107  		expected: argsSpec{
   108  			args:            "ubuntu@0.public:foo ubuntu@0.public:/foo -q",
   109  			hostKeyChecking: "yes",
   110  			knownHosts:      "0",
   111  		},
   112  	}, {
   113  		about: "scp from machine 0 to unit mysql/0 and extra args before",
   114  		args:  []string{"-q", "-r", "0:foo", "mysql/0:/foo"},
   115  		error: "option provided but not defined: -q",
   116  	}, {
   117  		about:       "scp two local files to unit mysql/0",
   118  		args:        []string{"file1", "file2", "mysql/0:/foo/"},
   119  		hostChecker: validAddresses("0.public"),
   120  		expected: argsSpec{
   121  			args:            "file1 file2 ubuntu@0.public:/foo/",
   122  			hostKeyChecking: "yes",
   123  			knownHosts:      "0",
   124  		},
   125  	}, {
   126  		about:       "scp from machine 0 to unit mysql/0 and multiple extra args",
   127  		args:        []string{"0:foo", "mysql/0:", "-r", "-v", "-q", "-l5"},
   128  		hostChecker: validAddresses("0.public"),
   129  		expected: argsSpec{
   130  			args:            "ubuntu@0.public:foo ubuntu@0.public: -r -v -q -l5",
   131  			hostKeyChecking: "yes",
   132  			knownHosts:      "0",
   133  		},
   134  	}, {
   135  		about:       "scp works with IPv6 addresses",
   136  		args:        []string{"2:foo", "bar"},
   137  		hostChecker: validAddresses("2001:db8::1"),
   138  		expected: argsSpec{
   139  			args:            `ubuntu@[2001:db8::1]:foo bar`,
   140  			hostKeyChecking: "yes",
   141  			knownHosts:      "2",
   142  		},
   143  	}, {
   144  		about:       "scp from machine 0 to unit mysql/0 with proxy",
   145  		args:        []string{"--proxy=true", "0:foo", "mysql/0:/bar"},
   146  		hostChecker: validAddresses("0.private"),
   147  		expected: argsSpec{
   148  			args:            "ubuntu@0.private:foo ubuntu@0.private:/bar",
   149  			withProxy:       true,
   150  			hostKeyChecking: "yes",
   151  			knownHosts:      "0",
   152  		},
   153  	}, {
   154  		about:       "scp from unit mysql/0 to machine 2 with a --",
   155  		args:        []string{"--", "-r", "-v", "mysql/0:foo", "2:", "-q", "-l5"},
   156  		hostChecker: validAddresses("0.public", "2001:db8::1"),
   157  		expected: argsSpec{
   158  			args:            "-r -v ubuntu@0.public:foo ubuntu@[2001:db8::1]: -q -l5",
   159  			hostKeyChecking: "yes",
   160  			knownHosts:      "0,2",
   161  		},
   162  	}, {
   163  		about:       "scp from unit mysql/0 to current dir as 'sam' user",
   164  		args:        []string{"sam@mysql/0:foo", "."},
   165  		hostChecker: validAddresses("0.public"),
   166  		expected: argsSpec{
   167  			args:            "sam@0.public:foo .",
   168  			hostKeyChecking: "yes",
   169  			knownHosts:      "0",
   170  		},
   171  	}, {
   172  		about: "scp with no such machine",
   173  		args:  []string{"5:foo", "bar"},
   174  		error: `machine 5 not found`,
   175  	}, {
   176  		about:       "scp from arbitrary host name to current dir",
   177  		args:        []string{"some.host:foo", "."},
   178  		hostChecker: validAddresses("some.host"),
   179  		expected: argsSpec{
   180  			args:            "some.host:foo .",
   181  			hostKeyChecking: "",
   182  		},
   183  	}, {
   184  		about:       "scp from arbitrary user & host to current dir",
   185  		args:        []string{"someone@some.host:foo", "."},
   186  		hostChecker: validAddresses("some.host"),
   187  		expected: argsSpec{
   188  			args:            "someone@some.host:foo .",
   189  			hostKeyChecking: "",
   190  		},
   191  	}, {
   192  		about:       "scp with arbitrary host name and an entity",
   193  		args:        []string{"some.host:foo", "0:"},
   194  		hostChecker: validAddresses("0.public"),
   195  		error:       `can't determine host keys for all targets: consider --no-host-key-checks`,
   196  	}, {
   197  		about:       "scp with arbitrary host name and an entity, --no-host-key-checks, --proxy (api v1)",
   198  		args:        []string{"--no-host-key-checks", "--proxy", "some.host:foo", "0:"},
   199  		hostChecker: validAddresses("some.host", "0.private"),
   200  		forceAPIv1:  true,
   201  		expected: argsSpec{
   202  			args:            "some.host:foo ubuntu@0.private:",
   203  			hostKeyChecking: "no",
   204  			withProxy:       true,
   205  			knownHosts:      "null",
   206  		},
   207  	}, {
   208  		about: "scp with no arguments",
   209  		args:  nil,
   210  		error: `at least two arguments required`,
   211  	},
   212  }
   213  
   214  func (s *SCPSuite) TestSCPCommand(c *gc.C) {
   215  	s.setupModel(c)
   216  
   217  	for i, t := range scpTests {
   218  		c.Logf("test %d: %s -> %s\n", i, t.about, t.args)
   219  
   220  		s.setHostChecker(t.hostChecker)
   221  		s.setForceAPIv1(t.forceAPIv1)
   222  
   223  		ctx, err := cmdtesting.RunCommand(c, newSCPCommand(s.hostChecker), t.args...)
   224  		if t.error != "" {
   225  			c.Check(err, gc.ErrorMatches, t.error)
   226  		} else {
   227  			c.Assert(err, jc.ErrorIsNil)
   228  			// we suppress stdout from scp, so get the scp args used
   229  			// from the "scp.args" file that the fake scp executable
   230  			// installed by SSHCommonSuite generates.
   231  			c.Check(cmdtesting.Stderr(ctx), gc.Equals, "")
   232  			c.Check(cmdtesting.Stdout(ctx), gc.Equals, "")
   233  			actual, err := ioutil.ReadFile(filepath.Join(s.binDir, "scp.args"))
   234  			c.Assert(err, jc.ErrorIsNil)
   235  			t.expected.check(c, string(actual))
   236  		}
   237  	}
   238  }