github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/plugin/rpc/cli_rpc_server_test.go (about) 1 package rpc_test 2 3 import ( 4 "net" 5 "net/rpc" 6 "time" 7 8 "github.com/cloudfoundry/cli/cf/terminal/fakes" 9 "github.com/cloudfoundry/cli/plugin" 10 . "github.com/cloudfoundry/cli/plugin/rpc" 11 io_helpers "github.com/cloudfoundry/cli/testhelpers/io" 12 "github.com/codegangsta/cli" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Server", func() { 18 var ( 19 err error 20 client *rpc.Client 21 rpcService *CliRpcService 22 ) 23 24 AfterEach(func() { 25 if client != nil { 26 client.Close() 27 } 28 }) 29 30 BeforeEach(func() { 31 rpc.DefaultServer = rpc.NewServer() 32 }) 33 34 Describe(".NewRpcService", func() { 35 BeforeEach(func() { 36 rpcService, err = NewRpcService(nil, nil, nil) 37 Expect(err).ToNot(HaveOccurred()) 38 }) 39 40 It("returns an err of another Rpc process is already registered", func() { 41 _, err := NewRpcService(nil, nil, nil) 42 Expect(err).To(HaveOccurred()) 43 }) 44 }) 45 46 Describe(".Stop", func() { 47 BeforeEach(func() { 48 rpcService, err = NewRpcService(nil, nil, nil) 49 Expect(err).ToNot(HaveOccurred()) 50 51 err := rpcService.Start() 52 Expect(err).ToNot(HaveOccurred()) 53 54 pingCli(rpcService.Port()) 55 }) 56 57 It("shuts down the rpc server", func() { 58 rpcService.Stop() 59 60 //give time for server to stop 61 time.Sleep(50 * time.Millisecond) 62 63 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 64 Expect(err).To(HaveOccurred()) 65 }) 66 }) 67 68 Describe(".Start", func() { 69 BeforeEach(func() { 70 rpcService, err = NewRpcService(nil, nil, nil) 71 Expect(err).ToNot(HaveOccurred()) 72 73 err := rpcService.Start() 74 Expect(err).ToNot(HaveOccurred()) 75 76 pingCli(rpcService.Port()) 77 }) 78 79 AfterEach(func() { 80 rpcService.Stop() 81 82 //give time for server to stop 83 time.Sleep(50 * time.Millisecond) 84 }) 85 86 It("Start an Rpc server for communication", func() { 87 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 88 Expect(err).ToNot(HaveOccurred()) 89 }) 90 }) 91 92 Describe(".SetPluginMetadata", func() { 93 var ( 94 metadata *plugin.PluginMetadata 95 ) 96 97 BeforeEach(func() { 98 rpcService, err = NewRpcService(nil, nil, nil) 99 Expect(err).ToNot(HaveOccurred()) 100 101 err := rpcService.Start() 102 Expect(err).ToNot(HaveOccurred()) 103 104 pingCli(rpcService.Port()) 105 106 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 107 Expect(err).ToNot(HaveOccurred()) 108 109 metadata = &plugin.PluginMetadata{ 110 Name: "foo", 111 Commands: []plugin.Command{ 112 {Name: "cmd_1", HelpText: "cm 1 help text"}, 113 {Name: "cmd_2", HelpText: "cmd 2 help text"}, 114 }, 115 } 116 }) 117 118 AfterEach(func() { 119 rpcService.Stop() 120 121 //give time for server to stop 122 time.Sleep(50 * time.Millisecond) 123 }) 124 125 It("set the rpc command's Return Data", func() { 126 var success bool 127 err = client.Call("CliRpcCmd.SetPluginMetadata", metadata, &success) 128 129 Expect(err).ToNot(HaveOccurred()) 130 Expect(success).To(BeTrue()) 131 Expect(rpcService.RpcCmd.PluginMetadata).To(Equal(metadata)) 132 }) 133 }) 134 135 Describe(".GetOutputAndReset", func() { 136 Context("success", func() { 137 BeforeEach(func() { 138 outputCapture := &fakes.FakeOutputCapture{} 139 outputCapture.GetOutputAndResetReturns([]string{"hi from command"}) 140 rpcService, err = NewRpcService(nil, outputCapture, nil) 141 Expect(err).ToNot(HaveOccurred()) 142 143 err := rpcService.Start() 144 Expect(err).ToNot(HaveOccurred()) 145 146 pingCli(rpcService.Port()) 147 }) 148 149 AfterEach(func() { 150 rpcService.Stop() 151 152 //give time for server to stop 153 time.Sleep(50 * time.Millisecond) 154 }) 155 156 It("should return the logs from the output capture", func() { 157 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 158 Expect(err).ToNot(HaveOccurred()) 159 var output []string 160 client.Call("CliRpcCmd.GetOutputAndReset", false, &output) 161 162 Expect(output).To(Equal([]string{"hi from command"})) 163 }) 164 }) 165 }) 166 167 Describe("disabling terminal output", func() { 168 var terminalOutputSwitch *fakes.FakeTerminalOutputSwitch 169 170 BeforeEach(func() { 171 terminalOutputSwitch = &fakes.FakeTerminalOutputSwitch{} 172 rpcService, err = NewRpcService(nil, nil, terminalOutputSwitch) 173 Expect(err).ToNot(HaveOccurred()) 174 175 err := rpcService.Start() 176 Expect(err).ToNot(HaveOccurred()) 177 178 pingCli(rpcService.Port()) 179 }) 180 181 It("should disable the terminal output switch", func() { 182 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 183 Expect(err).ToNot(HaveOccurred()) 184 185 var success bool 186 err = client.Call("CliRpcCmd.DisableTerminalOutput", true, &success) 187 188 Expect(err).ToNot(HaveOccurred()) 189 Expect(success).To(BeTrue()) 190 Expect(terminalOutputSwitch.DisableTerminalOutputCallCount()).To(Equal(1)) 191 Expect(terminalOutputSwitch.DisableTerminalOutputArgsForCall(0)).To(Equal(true)) 192 }) 193 }) 194 195 Describe(".CallCoreCommand", func() { 196 Context("success", func() { 197 BeforeEach(func() { 198 app := &cli.App{ 199 Commands: []cli.Command{ 200 { 201 Name: "test_cmd", 202 Description: "test_cmd description", 203 Usage: "test_cmd usage", 204 Action: func(context *cli.Context) { 205 return 206 }, 207 }, 208 }, 209 } 210 211 outputCapture := &fakes.FakeOutputCapture{} 212 213 rpcService, err = NewRpcService(app, outputCapture, nil) 214 Expect(err).ToNot(HaveOccurred()) 215 216 err := rpcService.Start() 217 Expect(err).ToNot(HaveOccurred()) 218 219 pingCli(rpcService.Port()) 220 }) 221 222 AfterEach(func() { 223 rpcService.Stop() 224 225 //give time for server to stop 226 time.Sleep(50 * time.Millisecond) 227 }) 228 229 It("calls the code gangsta cli App command", func() { 230 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 231 Expect(err).ToNot(HaveOccurred()) 232 233 var success bool 234 err = client.Call("CliRpcCmd.CallCoreCommand", []string{"test_cmd"}, &success) 235 236 Expect(err).ToNot(HaveOccurred()) 237 Expect(success).To(BeTrue()) 238 }) 239 }) 240 241 Context("fail", func() { 242 BeforeEach(func() { 243 app := &cli.App{ 244 Commands: []cli.Command{ 245 { 246 Name: "test_cmd", 247 Description: "test_cmd description", 248 Usage: "test_cmd usage", 249 Action: func(context *cli.Context) { 250 panic("ERROR") 251 }, 252 }, 253 }, 254 } 255 outputCapture := &fakes.FakeOutputCapture{} 256 rpcService, err = NewRpcService(app, outputCapture, nil) 257 Expect(err).ToNot(HaveOccurred()) 258 259 err := rpcService.Start() 260 Expect(err).ToNot(HaveOccurred()) 261 262 pingCli(rpcService.Port()) 263 }) 264 265 It("returns false in success if the command cannot be found", func() { 266 io_helpers.CaptureOutput(func() { 267 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 268 Expect(err).ToNot(HaveOccurred()) 269 270 var success bool 271 err = client.Call("CliRpcCmd.CallCoreCommand", []string{"not_a_cmd"}, &success) 272 Expect(success).To(BeFalse()) 273 Expect(err).ToNot(HaveOccurred()) 274 }) 275 }) 276 277 It("returns an error if a command cannot parse provided flags", func() { 278 io_helpers.CaptureOutput(func() { 279 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 280 Expect(err).ToNot(HaveOccurred()) 281 282 var success bool 283 err = client.Call("CliRpcCmd.CallCoreCommand", []string{"test_cmd", "-invalid_flag"}, &success) 284 285 Expect(err).To(HaveOccurred()) 286 Expect(success).To(BeFalse()) 287 }) 288 }) 289 290 It("recovers from a panic from any core command", func() { 291 client, err = rpc.Dial("tcp", "127.0.0.1:"+rpcService.Port()) 292 Expect(err).ToNot(HaveOccurred()) 293 294 var success bool 295 err = client.Call("CliRpcCmd.CallCoreCommand", []string{"test_cmd"}, &success) 296 297 Expect(success).To(BeFalse()) 298 }) 299 }) 300 }) 301 }) 302 303 func pingCli(port string) { 304 var connErr error 305 var conn net.Conn 306 for i := 0; i < 5; i++ { 307 conn, connErr = net.Dial("tcp", "127.0.0.1:"+port) 308 if connErr != nil { 309 time.Sleep(200 * time.Millisecond) 310 } else { 311 conn.Close() 312 break 313 } 314 } 315 Expect(connErr).ToNot(HaveOccurred()) 316 }