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 }