github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/command/common/install_plugin_from_repo_command_test.go (about) 1 package common_test 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "math/rand" 9 "os" 10 "runtime" 11 12 "code.cloudfoundry.org/cli/actor/actionerror" 13 "code.cloudfoundry.org/cli/actor/pluginaction" 14 "code.cloudfoundry.org/cli/api/plugin/pluginerror" 15 "code.cloudfoundry.org/cli/api/plugin/pluginfakes" 16 "code.cloudfoundry.org/cli/command/commandfakes" 17 . "code.cloudfoundry.org/cli/command/common" 18 "code.cloudfoundry.org/cli/command/common/commonfakes" 19 "code.cloudfoundry.org/cli/command/flag" 20 "code.cloudfoundry.org/cli/command/translatableerror" 21 "code.cloudfoundry.org/cli/integration/helpers" 22 "code.cloudfoundry.org/cli/util/configv3" 23 "code.cloudfoundry.org/cli/util/ui" 24 . "github.com/onsi/ginkgo" 25 . "github.com/onsi/ginkgo/extensions/table" 26 . "github.com/onsi/gomega" 27 . "github.com/onsi/gomega/gbytes" 28 ) 29 30 var _ = Describe("install-plugin command", func() { 31 var ( 32 cmd InstallPluginCommand 33 testUI *ui.UI 34 input *Buffer 35 fakeConfig *commandfakes.FakeConfig 36 fakeActor *commonfakes.FakeInstallPluginActor 37 fakeProgressBar *pluginfakes.FakeProxyReader 38 executeErr error 39 expectedErr error 40 pluginHome string 41 binaryName string 42 ) 43 44 BeforeEach(func() { 45 input = NewBuffer() 46 testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer()) 47 fakeConfig = new(commandfakes.FakeConfig) 48 fakeActor = new(commonfakes.FakeInstallPluginActor) 49 fakeProgressBar = new(pluginfakes.FakeProxyReader) 50 51 cmd = InstallPluginCommand{ 52 UI: testUI, 53 Config: fakeConfig, 54 Actor: fakeActor, 55 ProgressBar: fakeProgressBar, 56 } 57 58 var err error 59 pluginHome, err = ioutil.TempDir("", "some-pluginhome") 60 Expect(err).ToNot(HaveOccurred()) 61 fakeConfig.PluginHomeReturns(pluginHome) 62 binaryName = helpers.PrefixedRandomName("bin") 63 fakeConfig.BinaryNameReturns(binaryName) 64 }) 65 66 AfterEach(func() { 67 os.RemoveAll(pluginHome) 68 }) 69 70 JustBeforeEach(func() { 71 executeErr = cmd.Execute(nil) 72 }) 73 74 Describe("installing from a specific repo", func() { 75 var ( 76 pluginName string 77 pluginURL string 78 repoName string 79 repoURL string 80 ) 81 82 BeforeEach(func() { 83 pluginName = helpers.PrefixedRandomName("plugin") 84 pluginURL = helpers.PrefixedRandomName("http://") 85 repoName = helpers.PrefixedRandomName("repo") 86 repoURL = helpers.PrefixedRandomName("http://") 87 cmd.OptionalArgs.PluginNameOrLocation = flag.Path(pluginName) 88 cmd.RegisteredRepository = repoName 89 }) 90 91 When("the repo is not registered", func() { 92 BeforeEach(func() { 93 fakeActor.GetPluginRepositoryReturns(configv3.PluginRepository{}, actionerror.RepositoryNotRegisteredError{Name: repoName}) 94 }) 95 96 It("returns a RepositoryNotRegisteredError", func() { 97 Expect(executeErr).To(MatchError(actionerror.RepositoryNotRegisteredError{Name: repoName})) 98 99 Expect(fakeActor.GetPluginRepositoryCallCount()).To(Equal(1)) 100 repositoryNameArg := fakeActor.GetPluginRepositoryArgsForCall(0) 101 Expect(repositoryNameArg).To(Equal(repoName)) 102 }) 103 }) 104 105 When("the repository is registered", func() { 106 var platform string 107 108 BeforeEach(func() { 109 platform = helpers.PrefixedRandomName("platform") 110 fakeActor.GetPlatformStringReturns(platform) 111 fakeActor.GetPluginRepositoryReturns(configv3.PluginRepository{Name: repoName, URL: repoURL}, nil) 112 }) 113 114 When("getting repository information returns a json syntax error", func() { 115 var jsonErr error 116 BeforeEach(func() { 117 jsonErr = &json.SyntaxError{} 118 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, jsonErr) 119 }) 120 121 It("returns a JSONSyntaxError", func() { 122 Expect(executeErr).To(MatchError(jsonErr)) 123 }) 124 }) 125 126 When("getting the repository information errors", func() { 127 Context("with a generic error", func() { 128 BeforeEach(func() { 129 expectedErr = errors.New("some-client-error") 130 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, actionerror.FetchingPluginInfoFromRepositoryError{ 131 RepositoryName: "some-repo", 132 Err: expectedErr, 133 }) 134 }) 135 136 It("returns the wrapped client(request/http status) error", func() { 137 Expect(executeErr).To(MatchError(expectedErr)) 138 }) 139 }) 140 141 Context("with a RawHTTPStatusError error", func() { 142 var returnedErr pluginerror.RawHTTPStatusError 143 144 BeforeEach(func() { 145 returnedErr = pluginerror.RawHTTPStatusError{Status: "some-status"} 146 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, actionerror.FetchingPluginInfoFromRepositoryError{ 147 RepositoryName: "some-repo", 148 Err: returnedErr, 149 }) 150 }) 151 152 It("returns the wrapped client(request/http status) error", func() { 153 Expect(executeErr).To(MatchError(returnedErr)) 154 }) 155 }) 156 }) 157 158 When("the plugin can't be found in the repository", func() { 159 BeforeEach(func() { 160 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, actionerror.PluginNotFoundInAnyRepositoryError{PluginName: pluginName}) 161 }) 162 163 It("returns the PluginNotFoundInRepositoryError", func() { 164 Expect(executeErr).To(MatchError(translatableerror.PluginNotFoundInRepositoryError{BinaryName: binaryName, PluginName: pluginName, RepositoryName: repoName})) 165 166 Expect(fakeActor.GetPlatformStringCallCount()).To(Equal(1)) 167 platformGOOS, platformGOARCH := fakeActor.GetPlatformStringArgsForCall(0) 168 Expect(platformGOOS).To(Equal(runtime.GOOS)) 169 Expect(platformGOARCH).To(Equal(runtime.GOARCH)) 170 171 Expect(fakeActor.GetPluginInfoFromRepositoriesForPlatformCallCount()).To(Equal(1)) 172 pluginNameArg, pluginRepositoriesArg, pluginPlatform := fakeActor.GetPluginInfoFromRepositoriesForPlatformArgsForCall(0) 173 Expect(pluginNameArg).To(Equal(pluginName)) 174 Expect(pluginRepositoriesArg).To(Equal([]configv3.PluginRepository{{Name: repoName, URL: repoURL}})) 175 Expect(pluginPlatform).To(Equal(platform)) 176 }) 177 }) 178 179 When("a compatible binary can't be found in the repository", func() { 180 BeforeEach(func() { 181 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, actionerror.NoCompatibleBinaryError{}) 182 }) 183 184 It("returns the NoCompatibleBinaryError", func() { 185 Expect(executeErr).To(MatchError(actionerror.NoCompatibleBinaryError{})) 186 }) 187 }) 188 189 When("the plugin is found", func() { 190 var ( 191 checksum string 192 downloadedVersionString string 193 ) 194 195 BeforeEach(func() { 196 checksum = helpers.PrefixedRandomName("checksum") 197 downloadedVersionString = helpers.PrefixedRandomName("version") 198 199 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{Name: pluginName, Version: downloadedVersionString, URL: pluginURL, Checksum: checksum}, []string{repoName}, nil) 200 }) 201 202 When("the -f argument is given", func() { 203 BeforeEach(func() { 204 cmd.Force = true 205 }) 206 207 When("the plugin is already installed", func() { 208 BeforeEach(func() { 209 plugin := configv3.Plugin{ 210 Name: pluginName, 211 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 2}, 212 } 213 fakeConfig.GetPluginReturns(plugin, true) 214 fakeConfig.GetPluginCaseInsensitiveReturns(plugin, true) 215 }) 216 217 When("getting the binary errors", func() { 218 BeforeEach(func() { 219 expectedErr = errors.New("some-error") 220 fakeActor.DownloadExecutableBinaryFromURLReturns("", expectedErr) 221 }) 222 223 It("returns the error", func() { 224 Expect(executeErr).To(MatchError(expectedErr)) 225 226 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 227 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 228 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 229 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 230 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 231 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 232 233 Expect(testUI.Out).ToNot(Say("downloaded")) 234 Expect(fakeActor.GetAndValidatePluginCallCount()).To(Equal(0)) 235 236 Expect(fakeConfig.GetPluginCallCount()).To(Equal(1)) 237 Expect(fakeConfig.GetPluginArgsForCall(0)).To(Equal(pluginName)) 238 239 Expect(fakeActor.GetPlatformStringCallCount()).To(Equal(1)) 240 platformGOOS, platformGOARCH := fakeActor.GetPlatformStringArgsForCall(0) 241 Expect(platformGOOS).To(Equal(runtime.GOOS)) 242 Expect(platformGOARCH).To(Equal(runtime.GOARCH)) 243 244 Expect(fakeActor.GetPluginInfoFromRepositoriesForPlatformCallCount()).To(Equal(1)) 245 pluginNameArg, pluginRepositoriesArg, pluginPlatform := fakeActor.GetPluginInfoFromRepositoriesForPlatformArgsForCall(0) 246 Expect(pluginNameArg).To(Equal(pluginName)) 247 Expect(pluginRepositoriesArg).To(Equal([]configv3.PluginRepository{{Name: repoName, URL: repoURL}})) 248 Expect(pluginPlatform).To(Equal(platform)) 249 250 Expect(fakeActor.DownloadExecutableBinaryFromURLCallCount()).To(Equal(1)) 251 urlArg, dirArg, proxyReader := fakeActor.DownloadExecutableBinaryFromURLArgsForCall(0) 252 Expect(urlArg).To(Equal(pluginURL)) 253 Expect(dirArg).To(ContainSubstring("temp")) 254 Expect(proxyReader).To(Equal(fakeProgressBar)) 255 }) 256 }) 257 258 When("getting the binary succeeds", func() { 259 var execPath string 260 261 BeforeEach(func() { 262 execPath = helpers.PrefixedRandomName("some-path") 263 fakeActor.DownloadExecutableBinaryFromURLReturns(execPath, nil) 264 }) 265 266 When("the checksum fails", func() { 267 BeforeEach(func() { 268 fakeActor.ValidateFileChecksumReturns(false) 269 }) 270 271 It("returns the checksum error", func() { 272 Expect(executeErr).To(MatchError(translatableerror.InvalidChecksumError{})) 273 274 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 275 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 276 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 277 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 278 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 279 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 280 Expect(testUI.Out).ToNot(Say("Installing plugin")) 281 282 Expect(fakeActor.ValidateFileChecksumCallCount()).To(Equal(1)) 283 pathArg, checksumArg := fakeActor.ValidateFileChecksumArgsForCall(0) 284 Expect(pathArg).To(Equal(execPath)) 285 Expect(checksumArg).To(Equal(checksum)) 286 }) 287 }) 288 289 When("the checksum succeeds", func() { 290 BeforeEach(func() { 291 fakeActor.ValidateFileChecksumReturns(true) 292 }) 293 294 When("creating an executable copy errors", func() { 295 BeforeEach(func() { 296 fakeActor.CreateExecutableCopyReturns("", errors.New("some-error")) 297 }) 298 299 It("returns the error", func() { 300 Expect(executeErr).To(MatchError(errors.New("some-error"))) 301 Expect(testUI.Out).ToNot(Say("Installing plugin")) 302 303 Expect(fakeActor.CreateExecutableCopyCallCount()).To(Equal(1)) 304 pathArg, tempDirArg := fakeActor.CreateExecutableCopyArgsForCall(0) 305 Expect(pathArg).To(Equal(execPath)) 306 Expect(tempDirArg).To(ContainSubstring("temp")) 307 }) 308 }) 309 310 When("creating an exectuable copy succeeds", func() { 311 BeforeEach(func() { 312 fakeActor.CreateExecutableCopyReturns("copy-path", nil) 313 }) 314 315 When("validating the new plugin errors", func() { 316 BeforeEach(func() { 317 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{}, actionerror.PluginInvalidError{}) 318 }) 319 320 It("returns the error", func() { 321 Expect(executeErr).To(MatchError(actionerror.PluginInvalidError{})) 322 Expect(testUI.Out).ToNot(Say("Installing plugin")) 323 324 Expect(fakeActor.GetAndValidatePluginCallCount()).To(Equal(1)) 325 _, commandsArg, tempDirArg := fakeActor.GetAndValidatePluginArgsForCall(0) 326 Expect(commandsArg).To(Equal(Commands)) 327 Expect(tempDirArg).To(Equal("copy-path")) 328 }) 329 }) 330 331 When("validating the new plugin succeeds", func() { 332 var ( 333 pluginVersion configv3.PluginVersion 334 pluginVersionRegex string 335 ) 336 337 BeforeEach(func() { 338 major := rand.Int() 339 minor := rand.Int() 340 build := rand.Int() 341 pluginVersion = configv3.PluginVersion{Major: major, Minor: minor, Build: build} 342 pluginVersionRegex = fmt.Sprintf(`%d\.%d\.%d`, major, minor, build) 343 344 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{ 345 Name: pluginName, 346 Version: pluginVersion, 347 }, nil) 348 }) 349 350 When("uninstalling the existing errors", func() { 351 BeforeEach(func() { 352 expectedErr = errors.New("uninstall plugin error") 353 fakeActor.UninstallPluginReturns(expectedErr) 354 }) 355 356 It("returns the error", func() { 357 Expect(executeErr).To(MatchError(expectedErr)) 358 359 Expect(testUI.Out).To(Say(`Uninstalling existing plugin\.\.\.`)) 360 Expect(testUI.Out).ToNot(Say(`Plugin %s successfully uninstalled\.`, pluginName)) 361 362 Expect(fakeActor.UninstallPluginCallCount()).To(Equal(1)) 363 _, pluginNameArg := fakeActor.UninstallPluginArgsForCall(0) 364 Expect(pluginNameArg).To(Equal(pluginName)) 365 }) 366 }) 367 368 When("uninstalling the existing plugin succeeds", func() { 369 When("installing the new plugin errors", func() { 370 BeforeEach(func() { 371 expectedErr = errors.New("install plugin error") 372 fakeActor.InstallPluginFromPathReturns(expectedErr) 373 }) 374 375 It("returns the error", func() { 376 Expect(executeErr).To(MatchError(expectedErr)) 377 378 Expect(testUI.Out).To(Say(`Plugin %s successfully uninstalled\.`, pluginName)) 379 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 380 Expect(testUI.Out).ToNot(Say("successfully installed")) 381 382 Expect(fakeActor.InstallPluginFromPathCallCount()).To(Equal(1)) 383 pathArg, pluginArg := fakeActor.InstallPluginFromPathArgsForCall(0) 384 Expect(pathArg).To(Equal("copy-path")) 385 Expect(pluginArg).To(Equal(configv3.Plugin{ 386 Name: pluginName, 387 Version: pluginVersion, 388 })) 389 }) 390 }) 391 392 When("installing the new plugin succeeds", func() { 393 It("uninstalls the existing plugin and installs the new one", func() { 394 Expect(executeErr).ToNot(HaveOccurred()) 395 396 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 397 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 398 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 399 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 400 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 401 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 402 Expect(testUI.Out).To(Say(`Uninstalling existing plugin\.\.\.`)) 403 Expect(testUI.Out).To(Say("OK")) 404 Expect(testUI.Out).To(Say(`Plugin %s successfully uninstalled\.`, pluginName)) 405 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 406 Expect(testUI.Out).To(Say("OK")) 407 Expect(testUI.Out).To(Say(`%s %s successfully installed\.`, pluginName, pluginVersionRegex)) 408 }) 409 }) 410 }) 411 }) 412 }) 413 }) 414 }) 415 }) 416 417 When("the plugin is NOT already installed", func() { 418 When("getting the binary errors", func() { 419 BeforeEach(func() { 420 expectedErr = errors.New("some-error") 421 fakeActor.DownloadExecutableBinaryFromURLReturns("", expectedErr) 422 }) 423 424 It("returns the error", func() { 425 Expect(executeErr).To(MatchError(expectedErr)) 426 427 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 428 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 429 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 430 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 431 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 432 433 Expect(testUI.Out).ToNot(Say("downloaded")) 434 Expect(fakeActor.GetAndValidatePluginCallCount()).To(Equal(0)) 435 }) 436 }) 437 438 When("getting the binary succeeds", func() { 439 BeforeEach(func() { 440 fakeActor.DownloadExecutableBinaryFromURLReturns("some-path", nil) 441 }) 442 443 When("the checksum fails", func() { 444 BeforeEach(func() { 445 fakeActor.ValidateFileChecksumReturns(false) 446 }) 447 448 It("returns the checksum error", func() { 449 Expect(executeErr).To(MatchError(translatableerror.InvalidChecksumError{})) 450 451 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 452 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 453 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 454 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 455 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 456 Expect(testUI.Out).ToNot(Say("Installing plugin")) 457 }) 458 }) 459 460 When("the checksum succeeds", func() { 461 BeforeEach(func() { 462 fakeActor.ValidateFileChecksumReturns(true) 463 }) 464 465 When("creating an executable copy errors", func() { 466 BeforeEach(func() { 467 fakeActor.CreateExecutableCopyReturns("", errors.New("some-error")) 468 }) 469 470 It("returns the error", func() { 471 Expect(executeErr).To(MatchError(errors.New("some-error"))) 472 Expect(testUI.Out).ToNot(Say("Installing plugin")) 473 }) 474 }) 475 476 When("creating an executable copy succeeds", func() { 477 BeforeEach(func() { 478 fakeActor.CreateExecutableCopyReturns("copy-path", nil) 479 }) 480 481 When("validating the plugin errors", func() { 482 BeforeEach(func() { 483 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{}, actionerror.PluginInvalidError{}) 484 }) 485 486 It("returns the error", func() { 487 Expect(executeErr).To(MatchError(actionerror.PluginInvalidError{})) 488 Expect(testUI.Out).ToNot(Say("Installing plugin")) 489 }) 490 }) 491 492 When("validating the plugin succeeds", func() { 493 BeforeEach(func() { 494 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{ 495 Name: pluginName, 496 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 3}, 497 }, nil) 498 }) 499 500 When("installing the plugin errors", func() { 501 BeforeEach(func() { 502 expectedErr = errors.New("install plugin error") 503 fakeActor.InstallPluginFromPathReturns(expectedErr) 504 }) 505 506 It("returns the error", func() { 507 Expect(executeErr).To(MatchError(expectedErr)) 508 509 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 510 Expect(testUI.Out).ToNot(Say("successfully installed")) 511 }) 512 }) 513 514 When("installing the plugin succeeds", func() { 515 It("uninstalls the existing plugin and installs the new one", func() { 516 Expect(executeErr).ToNot(HaveOccurred()) 517 518 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 519 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 520 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 521 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 522 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 523 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 524 Expect(testUI.Out).To(Say("OK")) 525 Expect(testUI.Out).To(Say(`%s 1\.2\.3 successfully installed`, pluginName)) 526 }) 527 }) 528 }) 529 }) 530 }) 531 }) 532 }) 533 }) 534 535 When("the -f argument is not given (user is prompted for confirmation)", func() { 536 BeforeEach(func() { 537 fakeActor.ValidateFileChecksumReturns(true) 538 }) 539 540 When("the plugin is already installed", func() { 541 BeforeEach(func() { 542 plugin := configv3.Plugin{ 543 Name: pluginName, 544 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 2}, 545 } 546 fakeConfig.GetPluginReturns(plugin, true) 547 fakeConfig.GetPluginCaseInsensitiveReturns(plugin, true) 548 }) 549 550 When("the user chooses no", func() { 551 BeforeEach(func() { 552 input.Write([]byte("n\n")) 553 }) 554 555 It("cancels plugin installation", func() { 556 Expect(executeErr).ToNot(HaveOccurred()) 557 558 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 559 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 560 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 561 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 562 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 563 Expect(testUI.Out).To(Say(`Do you want to uninstall the existing plugin and install %s %s\? \[yN\]`, pluginName, downloadedVersionString)) 564 Expect(testUI.Out).To(Say(`Plugin installation cancelled\.`)) 565 }) 566 }) 567 568 When("the user chooses the default", func() { 569 BeforeEach(func() { 570 input.Write([]byte("\n")) 571 }) 572 573 It("cancels plugin installation", func() { 574 Expect(executeErr).ToNot(HaveOccurred()) 575 576 Expect(testUI.Out).To(Say(`Do you want to uninstall the existing plugin and install %s %s\? \[yN\]`, pluginName, downloadedVersionString)) 577 Expect(testUI.Out).To(Say(`Plugin installation cancelled\.`)) 578 }) 579 }) 580 581 When("the user input is invalid", func() { 582 BeforeEach(func() { 583 input.Write([]byte("e\n")) 584 }) 585 586 It("returns an error", func() { 587 Expect(executeErr).To(HaveOccurred()) 588 589 Expect(testUI.Out).To(Say(`Do you want to uninstall the existing plugin and install %s %s\? \[yN\]`, pluginName, downloadedVersionString)) 590 Expect(testUI.Out).ToNot(Say(`Plugin installation cancelled\.`)) 591 Expect(testUI.Out).ToNot(Say("Installing plugin")) 592 }) 593 }) 594 595 When("the user chooses yes", func() { 596 BeforeEach(func() { 597 input.Write([]byte("y\n")) 598 fakeActor.DownloadExecutableBinaryFromURLReturns("some-path", nil) 599 fakeActor.CreateExecutableCopyReturns("copy-path", nil) 600 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{ 601 Name: pluginName, 602 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 3}, 603 }, nil) 604 }) 605 606 It("installs the plugin", func() { 607 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 608 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 609 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 610 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 611 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 612 Expect(testUI.Out).To(Say(`Do you want to uninstall the existing plugin and install %s %s\? \[yN\]`, pluginName, downloadedVersionString)) 613 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 614 Expect(testUI.Out).To(Say(`Uninstalling existing plugin\.\.\.`)) 615 Expect(testUI.Out).To(Say("OK")) 616 Expect(testUI.Out).To(Say(`Plugin %s successfully uninstalled\.`, pluginName)) 617 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 618 Expect(testUI.Out).To(Say("OK")) 619 Expect(testUI.Out).To(Say(`%s 1\.2\.3 successfully installed`, pluginName)) 620 }) 621 }) 622 }) 623 624 When("the plugin is NOT already installed", func() { 625 When("the user chooses no", func() { 626 BeforeEach(func() { 627 input.Write([]byte("n\n")) 628 }) 629 630 It("cancels plugin installation", func() { 631 Expect(executeErr).ToNot(HaveOccurred()) 632 633 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 634 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 635 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 636 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 637 Expect(testUI.Out).To(Say(`Do you want to install the plugin %s\? \[yN\]`, pluginName)) 638 Expect(testUI.Out).To(Say(`Plugin installation cancelled\.`)) 639 }) 640 }) 641 642 When("the user chooses the default", func() { 643 BeforeEach(func() { 644 input.Write([]byte("\n")) 645 }) 646 647 It("cancels plugin installation", func() { 648 Expect(executeErr).ToNot(HaveOccurred()) 649 650 Expect(testUI.Out).To(Say(`Do you want to install the plugin %s\? \[yN\]`, pluginName)) 651 Expect(testUI.Out).To(Say(`Plugin installation cancelled\.`)) 652 }) 653 }) 654 655 When("the user input is invalid", func() { 656 BeforeEach(func() { 657 input.Write([]byte("e\n")) 658 }) 659 660 It("returns an error", func() { 661 Expect(executeErr).To(HaveOccurred()) 662 663 Expect(testUI.Out).To(Say(`Do you want to install the plugin %s\? \[yN\]`, pluginName)) 664 Expect(testUI.Out).ToNot(Say(`Plugin installation cancelled\.`)) 665 Expect(testUI.Out).ToNot(Say("Installing plugin")) 666 }) 667 }) 668 669 When("the user chooses yes", func() { 670 var execPath string 671 672 BeforeEach(func() { 673 input.Write([]byte("y\n")) 674 execPath = helpers.PrefixedRandomName("some-path") 675 fakeActor.DownloadExecutableBinaryFromURLReturns(execPath, nil) 676 fakeActor.CreateExecutableCopyReturns("copy-path", nil) 677 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{ 678 Name: pluginName, 679 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 3}, 680 }, nil) 681 }) 682 683 It("installs the plugin", func() { 684 Expect(executeErr).ToNot(HaveOccurred()) 685 686 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 687 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 688 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 689 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 690 Expect(testUI.Out).To(Say(`Do you want to install the plugin %s\? \[yN\]`, pluginName)) 691 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 692 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 693 Expect(testUI.Out).To(Say("OK")) 694 Expect(testUI.Out).To(Say(`%s 1\.2\.3 successfully installed`, pluginName)) 695 }) 696 }) 697 }) 698 }) 699 }) 700 }) 701 }) 702 703 Describe("installing from any registered repo", func() { 704 var ( 705 pluginName string 706 pluginURL string 707 repoName string 708 repoURL string 709 repo2Name string 710 repo2URL string 711 repo3Name string 712 repo3URL string 713 platform string 714 ) 715 716 BeforeEach(func() { 717 pluginName = helpers.PrefixedRandomName("plugin") 718 pluginURL = helpers.PrefixedRandomName("http://") 719 repoName = helpers.PrefixedRandomName("repoA") 720 repoURL = helpers.PrefixedRandomName("http://") 721 repo2Name = helpers.PrefixedRandomName("repoB") 722 repo2URL = helpers.PrefixedRandomName("http://") 723 repo3Name = helpers.PrefixedRandomName("repoC") 724 repo3URL = helpers.PrefixedRandomName("http://") 725 cmd.OptionalArgs.PluginNameOrLocation = flag.Path(pluginName) 726 727 platform = helpers.PrefixedRandomName("platform") 728 fakeActor.GetPlatformStringReturns(platform) 729 }) 730 731 When("there are no registered repos", func() { 732 BeforeEach(func() { 733 fakeConfig.PluginRepositoriesReturns([]configv3.PluginRepository{}) 734 }) 735 736 It("returns PluginNotFoundOnDiskOrInAnyRepositoryError", func() { 737 Expect(executeErr).To(MatchError(translatableerror.PluginNotFoundOnDiskOrInAnyRepositoryError{PluginName: pluginName, BinaryName: binaryName})) 738 }) 739 }) 740 741 When("there is one registered repo", func() { 742 BeforeEach(func() { 743 fakeConfig.PluginRepositoriesReturns([]configv3.PluginRepository{{Name: repoName, URL: repoURL}}) 744 }) 745 746 When("there is an error getting the plugin", func() { 747 BeforeEach(func() { 748 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, errors.New("some-error")) 749 }) 750 751 It("returns the error", func() { 752 Expect(executeErr).To(MatchError(errors.New("some-error"))) 753 }) 754 }) 755 756 When("the plugin is not found", func() { 757 BeforeEach(func() { 758 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, actionerror.PluginNotFoundInAnyRepositoryError{PluginName: pluginName}) 759 }) 760 761 It("returns the plugin not found error", func() { 762 Expect(executeErr).To(MatchError(translatableerror.PluginNotFoundOnDiskOrInAnyRepositoryError{PluginName: pluginName, BinaryName: binaryName})) 763 }) 764 }) 765 766 When("the plugin is found", func() { 767 var ( 768 checksum string 769 downloadedVersionString string 770 execPath string 771 ) 772 773 BeforeEach(func() { 774 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{Name: pluginName, Version: downloadedVersionString, URL: pluginURL, Checksum: checksum}, []string{repoName}, nil) 775 776 plugin := configv3.Plugin{ 777 Name: pluginName, 778 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 2}, 779 } 780 fakeConfig.GetPluginReturns(plugin, true) 781 fakeConfig.GetPluginCaseInsensitiveReturns(plugin, true) 782 783 execPath = helpers.PrefixedRandomName("some-path") 784 fakeActor.DownloadExecutableBinaryFromURLReturns(execPath, nil) 785 }) 786 787 When("the -f flag is provided, the plugin has already been installed, getting the binary succeeds, validating the checksum succeeds, creating an executable copy succeeds, validating the new plugin succeeds, uninstalling the existing plugin succeeds, and installing the plugin is succeeds", func() { 788 var ( 789 pluginVersion configv3.PluginVersion 790 pluginVersionRegex string 791 ) 792 793 BeforeEach(func() { 794 cmd.Force = true 795 796 fakeActor.ValidateFileChecksumReturns(true) 797 checksum = helpers.PrefixedRandomName("checksum") 798 799 fakeActor.CreateExecutableCopyReturns("copy-path", nil) 800 801 major := rand.Int() 802 minor := rand.Int() 803 build := rand.Int() 804 pluginVersion = configv3.PluginVersion{Major: major, Minor: minor, Build: build} 805 pluginVersionRegex = fmt.Sprintf(`%d\.%d\.%d`, major, minor, build) 806 807 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{ 808 Name: pluginName, 809 Version: pluginVersion, 810 }, nil) 811 }) 812 813 It("uninstalls the existing plugin and installs the new one", func() { 814 Expect(executeErr).ToNot(HaveOccurred()) 815 816 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 817 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 818 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 819 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 820 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 821 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 822 Expect(testUI.Out).To(Say(`Uninstalling existing plugin\.\.\.`)) 823 Expect(testUI.Out).To(Say("OK")) 824 Expect(testUI.Out).To(Say(`Plugin %s successfully uninstalled\.`, pluginName)) 825 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 826 Expect(testUI.Out).To(Say("OK")) 827 Expect(testUI.Out).To(Say(`%s %s successfully installed\.`, pluginName, pluginVersionRegex)) 828 }) 829 }) 830 831 When("the -f flag is not provided, the plugin has already been installed, getting the binary succeeds, but validating the checksum fails", func() { 832 BeforeEach(func() { 833 fakeActor.DownloadExecutableBinaryFromURLReturns("some-path", nil) 834 }) 835 836 When("the checksum fails", func() { 837 BeforeEach(func() { 838 cmd.Force = false 839 fakeActor.ValidateFileChecksumReturns(false) 840 input.Write([]byte("y\n")) 841 }) 842 843 It("returns the checksum error", func() { 844 Expect(executeErr).To(MatchError(translatableerror.InvalidChecksumError{})) 845 846 Expect(testUI.Out).To(Say(`Searching %s for plugin %s\.\.\.`, repoName, pluginName)) 847 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repoName)) 848 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 849 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 850 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 851 Expect(testUI.Out).To(Say(`Do you want to uninstall the existing plugin and install %s %s\? \[yN\]`, pluginName, downloadedVersionString)) 852 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repoName)) 853 }) 854 }) 855 }) 856 }) 857 }) 858 859 When("there are many registered repos", func() { 860 BeforeEach(func() { 861 fakeConfig.PluginRepositoriesReturns([]configv3.PluginRepository{{Name: repoName, URL: repoURL}, {Name: repo2Name, URL: repo2URL}, {Name: repo3Name, URL: repo3URL}}) 862 }) 863 864 When("getting the repository information errors", func() { 865 DescribeTable("properly propagates errors", 866 func(clientErr error, expectedErr error) { 867 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns( 868 pluginaction.PluginInfo{}, 869 nil, 870 clientErr) 871 872 executeErr = cmd.Execute(nil) 873 874 Expect(executeErr).To(MatchError(expectedErr)) 875 }, 876 877 Entry("when the error is a RawHTTPStatusError", 878 actionerror.FetchingPluginInfoFromRepositoryError{ 879 RepositoryName: "some-repo", 880 Err: pluginerror.RawHTTPStatusError{Status: "some-status"}, 881 }, 882 translatableerror.FetchingPluginInfoFromRepositoriesError{Message: "some-status", RepositoryName: "some-repo"}, 883 ), 884 885 Entry("when the error is a SSLValidationHostnameError", 886 actionerror.FetchingPluginInfoFromRepositoryError{ 887 RepositoryName: "some-repo", 888 Err: pluginerror.SSLValidationHostnameError{Message: "some-status"}, 889 }, 890 891 translatableerror.FetchingPluginInfoFromRepositoriesError{Message: "Hostname does not match SSL Certificate (some-status)", RepositoryName: "some-repo"}, 892 ), 893 894 Entry("when the error is an UnverifiedServerError", 895 actionerror.FetchingPluginInfoFromRepositoryError{ 896 RepositoryName: "some-repo", 897 Err: pluginerror.UnverifiedServerError{URL: "some-url"}, 898 }, 899 translatableerror.FetchingPluginInfoFromRepositoriesError{Message: "x509: certificate signed by unknown authority", RepositoryName: "some-repo"}, 900 ), 901 902 Entry("when the error is generic", 903 actionerror.FetchingPluginInfoFromRepositoryError{ 904 RepositoryName: "some-repo", 905 Err: errors.New("generic-error"), 906 }, 907 errors.New("generic-error"), 908 ), 909 ) 910 }) 911 912 When("the plugin can't be found in any repos", func() { 913 BeforeEach(func() { 914 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{}, nil, actionerror.PluginNotFoundInAnyRepositoryError{PluginName: pluginName}) 915 }) 916 917 It("returns PluginNotFoundOnDiskOrInAnyRepositoryError", func() { 918 Expect(executeErr).To(MatchError(translatableerror.PluginNotFoundOnDiskOrInAnyRepositoryError{PluginName: pluginName, BinaryName: binaryName})) 919 }) 920 }) 921 922 When("the plugin is found in one repo", func() { 923 var ( 924 checksum string 925 downloadedVersionString string 926 execPath string 927 ) 928 929 BeforeEach(func() { 930 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{Name: pluginName, Version: downloadedVersionString, URL: pluginURL, Checksum: checksum}, []string{repo2Name}, nil) 931 932 plugin := configv3.Plugin{ 933 Name: pluginName, 934 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 2}, 935 } 936 fakeConfig.GetPluginReturns(plugin, true) 937 fakeConfig.GetPluginCaseInsensitiveReturns(plugin, true) 938 939 execPath = helpers.PrefixedRandomName("some-path") 940 }) 941 942 When("the -f flag is provided, the plugin has already been installed, getting the binary succeeds, validating the checksum succeeds, creating an executable copy succeeds, validating the new plugin succeeds, uninstalling the existing plugin succeeds, and installing the plugin is succeeds", func() { 943 var pluginVersion configv3.PluginVersion 944 945 BeforeEach(func() { 946 cmd.Force = true 947 948 fakeActor.DownloadExecutableBinaryFromURLReturns(execPath, nil) 949 950 fakeActor.ValidateFileChecksumReturns(true) 951 checksum = helpers.PrefixedRandomName("checksum") 952 953 fakeActor.CreateExecutableCopyReturns("copy-path", nil) 954 955 major := rand.Int() 956 minor := rand.Int() 957 build := rand.Int() 958 959 pluginVersion = configv3.PluginVersion{Major: major, Minor: minor, Build: build} 960 961 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{ 962 Name: pluginName, 963 Version: pluginVersion, 964 }, nil) 965 }) 966 967 It("uninstalls the existing plugin and installs the new one", func() { 968 Expect(executeErr).ToNot(HaveOccurred()) 969 970 Expect(testUI.Out).To(Say(`Searching %s, %s, %s for plugin %s\.\.\.`, repoName, repo2Name, repo3Name, pluginName)) 971 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repo2Name)) 972 }) 973 }) 974 975 When("the -f flag is not provided, the plugin has already been installed, getting the binary succeeds fails", func() { 976 977 BeforeEach(func() { 978 cmd.Force = false 979 fakeActor.DownloadExecutableBinaryFromURLReturns("", errors.New("some-error")) 980 input.Write([]byte("y\n")) 981 }) 982 983 It("returns the checksum error", func() { 984 Expect(executeErr).To(MatchError(errors.New("some-error"))) 985 986 Expect(testUI.Out).To(Say(`Searching %s, %s, %s for plugin %s\.\.\.`, repoName, repo2Name, repo3Name, pluginName)) 987 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s", pluginName, downloadedVersionString, repo2Name)) 988 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 989 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 990 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 991 Expect(testUI.Out).To(Say(`Do you want to uninstall the existing plugin and install %s %s\? \[yN\]`, pluginName, downloadedVersionString)) 992 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repo2Name)) 993 }) 994 }) 995 }) 996 997 When("the plugin is found in multiple repos", func() { 998 var ( 999 checksum string 1000 downloadedVersionString string 1001 execPath string 1002 ) 1003 1004 BeforeEach(func() { 1005 downloadedVersionString = helpers.PrefixedRandomName("version") 1006 1007 fakeActor.GetPluginInfoFromRepositoriesForPlatformReturns(pluginaction.PluginInfo{Name: pluginName, Version: downloadedVersionString, URL: pluginURL, Checksum: checksum}, []string{repo2Name, repo3Name}, nil) 1008 1009 plugin := configv3.Plugin{ 1010 Name: pluginName, 1011 Version: configv3.PluginVersion{Major: 1, Minor: 2, Build: 2}, 1012 } 1013 fakeConfig.GetPluginReturns(plugin, true) 1014 fakeConfig.GetPluginCaseInsensitiveReturns(plugin, true) 1015 1016 execPath = helpers.PrefixedRandomName("some-path") 1017 fakeActor.DownloadExecutableBinaryFromURLReturns(execPath, nil) 1018 }) 1019 1020 When("the -f flag is provided, the plugin has already been installed, getting the binary succeeds, validating the checksum succeeds, creating an executable copy succeeds, validating the new plugin succeeds, uninstalling the existing plugin succeeds, and installing the plugin is succeeds", func() { 1021 var ( 1022 pluginVersion configv3.PluginVersion 1023 pluginVersionRegex string 1024 ) 1025 1026 BeforeEach(func() { 1027 cmd.Force = true 1028 1029 fakeActor.ValidateFileChecksumReturns(true) 1030 checksum = helpers.PrefixedRandomName("checksum") 1031 1032 fakeActor.CreateExecutableCopyReturns("copy-path", nil) 1033 1034 major := rand.Int() 1035 minor := rand.Int() 1036 build := rand.Int() 1037 pluginVersion = configv3.PluginVersion{Major: major, Minor: minor, Build: build} 1038 pluginVersionRegex = fmt.Sprintf(`%d\.%d\.%d`, major, minor, build) 1039 1040 fakeActor.GetAndValidatePluginReturns(configv3.Plugin{ 1041 Name: pluginName, 1042 Version: pluginVersion, 1043 }, nil) 1044 }) 1045 1046 It("uninstalls the existing plugin and installs the new one", func() { 1047 Expect(executeErr).ToNot(HaveOccurred()) 1048 1049 Expect(testUI.Out).To(Say(`Searching %s, %s, %s for plugin %s\.\.\.`, repoName, repo2Name, repo3Name, pluginName)) 1050 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s, %s", pluginName, downloadedVersionString, repo2Name, repo3Name)) 1051 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 1052 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 1053 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 1054 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repo2Name)) 1055 Expect(testUI.Out).To(Say(`Uninstalling existing plugin\.\.\.`)) 1056 Expect(testUI.Out).To(Say("OK")) 1057 Expect(testUI.Out).To(Say(`Plugin %s successfully uninstalled\.`, pluginName)) 1058 Expect(testUI.Out).To(Say(`Installing plugin %s\.\.\.`, pluginName)) 1059 Expect(testUI.Out).To(Say("OK")) 1060 Expect(testUI.Out).To(Say(`%s %s successfully installed\.`, pluginName, pluginVersionRegex)) 1061 }) 1062 }) 1063 1064 When("the -f flag is not provided, the plugin has already been installed, getting the binary succeeds, validating the checksum succeeds, but creating an executable copy fails", func() { 1065 1066 BeforeEach(func() { 1067 cmd.Force = false 1068 fakeActor.ValidateFileChecksumReturns(true) 1069 checksum = helpers.PrefixedRandomName("checksum") 1070 1071 fakeActor.CreateExecutableCopyReturns("", errors.New("some-error")) 1072 input.Write([]byte("y\n")) 1073 }) 1074 1075 It("returns the error", func() { 1076 Expect(executeErr).To(MatchError(errors.New("some-error"))) 1077 1078 Expect(testUI.Out).To(Say(`Searching %s, %s, %s for plugin %s\.\.\.`, repoName, repo2Name, repo3Name, pluginName)) 1079 Expect(testUI.Out).To(Say("Plugin %s %s found in: %s, %s", pluginName, downloadedVersionString, repo2Name, repo3Name)) 1080 Expect(testUI.Out).To(Say(`Plugin %s 1\.2\.2 is already installed\.`, pluginName)) 1081 Expect(testUI.Out).To(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`)) 1082 Expect(testUI.Out).To(Say(`Install and use plugins at your own risk\.`)) 1083 Expect(testUI.Out).To(Say(`Do you want to uninstall the existing plugin and install %s %s\? \[yN\]`, pluginName, downloadedVersionString)) 1084 Expect(testUI.Out).To(Say(`Starting download of plugin binary from repository %s\.\.\.`, repo2Name)) 1085 }) 1086 }) 1087 }) 1088 }) 1089 }) 1090 })