github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/cf/ssh/options/ssh_options_test.go (about) 1 package options_test 2 3 import ( 4 "code.cloudfoundry.org/cli/cf/flags" 5 "code.cloudfoundry.org/cli/cf/ssh/options" 6 7 . "github.com/onsi/ginkgo" 8 . "github.com/onsi/gomega" 9 ) 10 11 var _ = Describe("SSHOptions", func() { 12 var ( 13 opts *options.SSHOptions 14 args []string 15 parseError error 16 fc flags.FlagContext 17 ) 18 19 Describe("Parse", func() { 20 BeforeEach(func() { 21 fc = flags.New() 22 fc.NewStringSliceFlag("L", "", "") 23 fc.NewStringSliceFlag("command", "c", "") 24 fc.NewIntFlag("app-instance-index", "i", "") 25 fc.NewBoolFlag("skip-host-validation", "k", "") 26 fc.NewBoolFlag("skip-remote-execution", "N", "") 27 fc.NewBoolFlag("request-pseudo-tty", "t", "") 28 fc.NewBoolFlag("force-pseudo-tty", "tt", "") 29 fc.NewBoolFlag("disable-pseudo-tty", "T", "") 30 31 args = []string{} 32 parseError = nil 33 }) 34 35 JustBeforeEach(func() { 36 err := fc.Parse(args...) 37 Expect(err).NotTo(HaveOccurred()) 38 39 opts, parseError = options.NewSSHOptions(fc) 40 }) 41 42 Context("when an app name is provided", func() { 43 Context("as the only argument", func() { 44 BeforeEach(func() { 45 args = append(args, "app-1") 46 }) 47 48 It("populates the AppName field", func() { 49 Expect(parseError).NotTo(HaveOccurred()) 50 Expect(opts.AppName).To(Equal("app-1")) 51 }) 52 }) 53 54 Context("as the last argument", func() { 55 BeforeEach(func() { 56 args = append(args, "-i", "3", "app-1") 57 }) 58 59 It("populates the AppName field", func() { 60 Expect(parseError).NotTo(HaveOccurred()) 61 Expect(opts.AppName).To(Equal("app-1")) 62 }) 63 }) 64 }) 65 66 Context("when --skip-host-validation is set", func() { 67 BeforeEach(func() { 68 args = append(args, "app-name", "--skip-host-validation") 69 }) 70 71 It("disables host key validation", func() { 72 Expect(parseError).ToNot(HaveOccurred()) 73 Expect(opts.SkipHostValidation).To(BeTrue()) 74 Expect(opts.AppName).To(Equal("app-name")) 75 }) 76 }) 77 78 Context("when -k is set", func() { 79 BeforeEach(func() { 80 args = append(args, "app-name", "-k") 81 }) 82 83 It("disables host key validation", func() { 84 Expect(parseError).ToNot(HaveOccurred()) 85 Expect(opts.SkipHostValidation).To(BeTrue()) 86 Expect(opts.AppName).To(Equal("app-name")) 87 }) 88 }) 89 90 Context("when the -t and -T flags are not used", func() { 91 BeforeEach(func() { 92 args = append(args, "app-name") 93 }) 94 95 It("requests auto tty allocation", func() { 96 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYAuto)) 97 }) 98 }) 99 100 Context("when the -T flag is provided", func() { 101 BeforeEach(func() { 102 args = append(args, "app-name", "-T") 103 }) 104 105 It("disables tty allocation", func() { 106 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYNo)) 107 }) 108 }) 109 110 Context("when the -t flag is used", func() { 111 BeforeEach(func() { 112 args = append(args, "app-name", "-t") 113 }) 114 115 It("requests tty allocation", func() { 116 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYYes)) 117 }) 118 }) 119 120 Context("when the -tt flag is used", func() { 121 BeforeEach(func() { 122 args = append(args, "app-name", "-tt") 123 }) 124 It("foces tty allocation", func() { 125 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYForce)) 126 }) 127 }) 128 129 Context("when both -t, -tt are specified", func() { 130 BeforeEach(func() { 131 args = append(args, "app-name", "-t", "-tt") 132 }) 133 134 It("forces tty allocation", func() { 135 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYForce)) 136 }) 137 }) 138 139 Context("when -t, -tt and -T are all specified", func() { 140 BeforeEach(func() { 141 args = append(args, "app-name", "-t", "-tt", "-T") 142 }) 143 144 It("disables tty allocation", func() { 145 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYNo)) 146 }) 147 }) 148 149 Context("when command is provided with -c", func() { 150 Context("when -c is used once", func() { 151 BeforeEach(func() { 152 args = append(args, "app-name", "-k", "-t", "-c", "true") 153 }) 154 155 It("handles the app and command correctly", func() { 156 Expect(opts.SkipHostValidation).To(BeTrue()) 157 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYYes)) 158 Expect(opts.AppName).To(Equal("app-name")) 159 Expect(opts.Command).To(ConsistOf("true")) 160 }) 161 }) 162 163 Context("when -c is used more than once", func() { 164 BeforeEach(func() { 165 args = append(args, "-k", "app-name", "-t", "-c", "echo", "-c", "-n", "-c", "hello!") 166 }) 167 168 It("handles the app and command correctly", func() { 169 Expect(opts.SkipHostValidation).To(BeTrue()) 170 Expect(opts.TerminalRequest).To(Equal(options.RequestTTYYes)) 171 Expect(opts.AppName).To(Equal("app-name")) 172 Expect(opts.Command).To(ConsistOf("echo", "-n", "hello!")) 173 }) 174 }) 175 }) 176 177 Context("when local port forwarding is requested", func() { 178 BeforeEach(func() { 179 args = append(args, "app-name") 180 }) 181 182 Context("without an explicit bind address", func() { 183 BeforeEach(func() { 184 args = append(args, "-L", "9999:remote:8888") 185 }) 186 187 It("sets the forward spec", func() { 188 Expect(parseError).NotTo(HaveOccurred()) 189 Expect(opts.ForwardSpecs).To(ConsistOf(options.ForwardSpec{ListenAddress: "localhost:9999", ConnectAddress: "remote:8888"})) 190 }) 191 }) 192 193 Context("with an explit bind address", func() { 194 BeforeEach(func() { 195 args = append(args, "-L", "explicit:9999:remote:8888") 196 }) 197 198 It("sets the forward spec", func() { 199 Expect(parseError).NotTo(HaveOccurred()) 200 Expect(opts.ForwardSpecs).To(ConsistOf(options.ForwardSpec{ListenAddress: "explicit:9999", ConnectAddress: "remote:8888"})) 201 }) 202 }) 203 204 Context("with an explicit ipv6 bind address", func() { 205 BeforeEach(func() { 206 args = append(args, "-L", "[::]:9999:remote:8888") 207 }) 208 209 It("sets the forward spec", func() { 210 Expect(parseError).NotTo(HaveOccurred()) 211 Expect(opts.ForwardSpecs).To(ConsistOf(options.ForwardSpec{ListenAddress: "[::]:9999", ConnectAddress: "remote:8888"})) 212 }) 213 }) 214 215 Context("with an empty bind address", func() { 216 BeforeEach(func() { 217 args = append(args, "-L", ":9999:remote:8888") 218 }) 219 220 It("sets the forward spec", func() { 221 Expect(parseError).NotTo(HaveOccurred()) 222 Expect(opts.ForwardSpecs).To(ConsistOf(options.ForwardSpec{ListenAddress: ":9999", ConnectAddress: "remote:8888"})) 223 }) 224 }) 225 226 Context("with * as the bind address", func() { 227 BeforeEach(func() { 228 args = append(args, "-L", "*:9999:remote:8888") 229 }) 230 231 It("sets the forward spec", func() { 232 Expect(parseError).NotTo(HaveOccurred()) 233 Expect(opts.ForwardSpecs).To(ConsistOf(options.ForwardSpec{ListenAddress: ":9999", ConnectAddress: "remote:8888"})) 234 }) 235 }) 236 237 Context("with an explicit ipv6 connect address", func() { 238 BeforeEach(func() { 239 args = append(args, "-L", "[::]:9999:[2001:db8::1]:8888") 240 }) 241 242 It("sets the forward spec", func() { 243 Expect(parseError).NotTo(HaveOccurred()) 244 Expect(opts.ForwardSpecs).To(ConsistOf(options.ForwardSpec{ListenAddress: "[::]:9999", ConnectAddress: "[2001:db8::1]:8888"})) 245 }) 246 }) 247 248 Context("with a missing bracket", func() { 249 BeforeEach(func() { 250 args = append(args, "-L", "localhost:9999:[example.com:8888") 251 }) 252 253 It("returns an error", func() { 254 Expect(parseError).To(MatchError(`Argument missing closing bracket: "[example.com:8888"`)) 255 }) 256 }) 257 258 Context("when a closing bracket is not followed by a colon", func() { 259 BeforeEach(func() { 260 args = append(args, "-L", "localhost:9999:[example.com]8888") 261 }) 262 263 It("returns an error", func() { 264 Expect(parseError).To(MatchError(`Unexpected token: "8888"`)) 265 }) 266 }) 267 268 Context("when multiple local port forward options are specified", func() { 269 BeforeEach(func() { 270 args = append(args, "-L", "9999:remote:8888") 271 args = append(args, "-L", "8080:remote:80") 272 }) 273 274 It("sets the forward specs", func() { 275 Expect(parseError).NotTo(HaveOccurred()) 276 Expect(opts.ForwardSpecs).To(ConsistOf( 277 options.ForwardSpec{ListenAddress: "localhost:9999", ConnectAddress: "remote:8888"}, 278 options.ForwardSpec{ListenAddress: "localhost:8080", ConnectAddress: "remote:80"}, 279 )) 280 }) 281 }) 282 }) 283 284 Context("when -N is specified", func() { 285 BeforeEach(func() { 286 args = append(args, "app-name", "-N") 287 }) 288 289 It("indicates that no remote command should be run", func() { 290 Expect(parseError).ToNot(HaveOccurred()) 291 Expect(opts.SkipRemoteExecution).To(BeTrue()) 292 Expect(opts.AppName).To(Equal("app-name")) 293 }) 294 }) 295 }) 296 297 })