github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/create_buildpack_command_test.go (about) 1 package v7_test 2 3 import ( 4 "errors" 5 6 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/actionerror" 7 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action" 8 "github.com/LukasHeimann/cloudfoundrycli/v8/api/cloudcontroller/ccerror" 9 "github.com/LukasHeimann/cloudfoundrycli/v8/api/cloudcontroller/ccv3" 10 "github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes" 11 "github.com/LukasHeimann/cloudfoundrycli/v8/command/flag" 12 "github.com/LukasHeimann/cloudfoundrycli/v8/command/translatableerror" 13 . "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7" 14 "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes" 15 "github.com/LukasHeimann/cloudfoundrycli/v8/resources" 16 "github.com/LukasHeimann/cloudfoundrycli/v8/types" 17 "github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3" 18 "github.com/LukasHeimann/cloudfoundrycli/v8/util/ui" 19 20 . "github.com/onsi/ginkgo" 21 . "github.com/onsi/gomega" 22 . "github.com/onsi/gomega/gbytes" 23 ) 24 25 var _ = Describe("create buildpack Command", func() { 26 var ( 27 cmd CreateBuildpackCommand 28 testUI *ui.UI 29 fakeConfig *commandfakes.FakeConfig 30 fakeSharedActor *commandfakes.FakeSharedActor 31 fakeActor *v7fakes.FakeActor 32 executeErr error 33 args []string 34 binaryName string 35 buildpackName string 36 buildpackPath string 37 ) 38 39 BeforeEach(func() { 40 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 41 fakeConfig = new(commandfakes.FakeConfig) 42 fakeSharedActor = new(commandfakes.FakeSharedActor) 43 fakeActor = new(v7fakes.FakeActor) 44 args = nil 45 buildpackName = "some-buildpack" 46 buildpackPath = "/path/to/buildpack.zip" 47 48 cmd = CreateBuildpackCommand{ 49 RequiredArgs: flag.CreateBuildpackArgs{ 50 Buildpack: buildpackName, 51 Path: flag.PathWithExistenceCheckOrURL(buildpackPath), 52 Position: 7, 53 }, 54 BaseCommand: BaseCommand{ 55 UI: testUI, 56 Config: fakeConfig, 57 SharedActor: fakeSharedActor, 58 Actor: fakeActor, 59 }, 60 } 61 62 binaryName = "faceman" 63 fakeConfig.BinaryNameReturns(binaryName) 64 }) 65 66 JustBeforeEach(func() { 67 executeErr = cmd.Execute(args) 68 }) 69 70 When("the environment is not set up correctly", func() { 71 BeforeEach(func() { 72 fakeSharedActor.CheckTargetReturns(actionerror.NotLoggedInError{BinaryName: binaryName}) 73 }) 74 75 It("returns an error", func() { 76 Expect(executeErr).To(MatchError(actionerror.NotLoggedInError{BinaryName: binaryName})) 77 78 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 79 checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0) 80 Expect(checkTargetedOrg).To(BeFalse()) 81 Expect(checkTargetedSpace).To(BeFalse()) 82 }) 83 }) 84 85 When("the environment is setup correctly", func() { 86 BeforeEach(func() { 87 fakeActor.GetCurrentUserReturns(configv3.User{Name: "the-user"}, nil) 88 }) 89 90 It("should print text indicating it is creating a buildpack", func() { 91 Expect(executeErr).NotTo(HaveOccurred()) 92 Expect(testUI.Out).To(Say(`Creating buildpack %s as the-user\.\.\.`, buildpackName)) 93 }) 94 95 When("preparing the buildpack bits fails", func() { 96 BeforeEach(func() { 97 fakeActor.PrepareBuildpackBitsReturns("some/invalid/path", errors.New("some-prepare-bp-error")) 98 }) 99 100 It("returns an error", func() { 101 Expect(executeErr).To(MatchError("some-prepare-bp-error")) 102 Expect(fakeActor.PrepareBuildpackBitsCallCount()).To(Equal(1)) 103 }) 104 }) 105 106 When("Preparing the buildpack bits succeeds", func() { 107 108 BeforeEach(func() { 109 fakeActor.PrepareBuildpackBitsReturns("buildpack.zip", nil) 110 }) 111 112 When("creating the buildpack fails", func() { 113 BeforeEach(func() { 114 fakeActor.CreateBuildpackReturns( 115 resources.Buildpack{}, 116 v7action.Warnings{"warning-1"}, 117 actionerror.BuildpackNameTakenError{Name: "this-error-occurred"}, 118 ) 119 }) 120 It("errors and prints all warnings", func() { 121 Expect(executeErr).To(Equal(actionerror.BuildpackNameTakenError{Name: "this-error-occurred"})) 122 Expect(testUI.Err).To(Say("warning-1")) 123 }) 124 }) 125 126 When("The disabled flag is set", func() { 127 BeforeEach(func() { 128 cmd.Disable = true 129 buildpack := resources.Buildpack{ 130 Name: buildpackName, 131 Enabled: types.NullBool{Value: false, IsSet: true}, 132 } 133 fakeActor.CreateBuildpackReturns(buildpack, v7action.Warnings{"some-create-warning-1"}, nil) 134 }) 135 136 It("correctly creates a disabled buildpack", func() { 137 buildpack := fakeActor.CreateBuildpackArgsForCall(0) 138 Expect(buildpack.Name).To(Equal(buildpackName)) 139 Expect(buildpack.Enabled.Value).To(BeFalse()) 140 }) 141 }) 142 143 When("creating buildpack succeeds", func() { 144 BeforeEach(func() { 145 buildpack := resources.Buildpack{ 146 Name: buildpackName, 147 Position: types.NullInt{Value: 1, IsSet: true}, 148 Enabled: types.NullBool{Value: true, IsSet: true}, 149 Locked: types.NullBool{Value: false, IsSet: true}, 150 Filename: "buildpack-1.file", 151 Stack: "buildpack-1-stack", 152 GUID: "some-guid", 153 } 154 fakeActor.CreateBuildpackReturns(buildpack, v7action.Warnings{"some-create-warning-1"}, nil) 155 }) 156 157 It("correctly created the buildpack", func() { 158 buildpack := fakeActor.CreateBuildpackArgsForCall(0) 159 Expect(buildpack.Name).To(Equal(buildpackName)) 160 Expect(buildpack.Position.Value).To(Equal(7)) 161 }) 162 163 It("prints any warnings and uploads the bits", func() { 164 Expect(executeErr).NotTo(HaveOccurred()) 165 Expect(testUI.Out).To(Say("OK")) 166 Expect(testUI.Err).To(Say("some-create-warning-1")) 167 Expect(testUI.Out).To(Say(`Uploading buildpack %s as the-user\.\.\.`, buildpackName)) 168 }) 169 170 It("Displays it is starting the upload", func() { 171 Expect(executeErr).ToNot(HaveOccurred()) 172 Expect(testUI.Out).To(Say("Uploading buildpack %s as the-user", buildpackName)) 173 174 Expect(fakeActor.PrepareBuildpackBitsCallCount()).To(Equal(1)) 175 path, _, _ := fakeActor.PrepareBuildpackBitsArgsForCall(0) 176 Expect(path).To(Equal(buildpackPath)) 177 }) 178 179 When("uploading the buildpack fails due to an auth token expired error", func() { 180 BeforeEach(func() { 181 fakeActor.UploadBuildpackReturns( 182 ccv3.JobURL(""), 183 v7action.Warnings{"some-create-bp-with-auth-warning"}, 184 ccerror.InvalidAuthTokenError{Message: "token expired"}, 185 ) 186 }) 187 188 It("alerts the user and retries the upload", func() { 189 Expect(testUI.Err).To(Say("Failed to upload buildpack due to auth token expiration, retrying...")) 190 Expect(fakeActor.UploadBuildpackCallCount()).To(Equal(2)) 191 }) 192 }) 193 194 When("Uploading the buildpack fails due to a generic error", func() { 195 BeforeEach(func() { 196 fakeActor.UploadBuildpackReturns( 197 ccv3.JobURL(""), 198 v7action.Warnings{"warning-2"}, 199 errors.New("some-error"), 200 ) 201 }) 202 203 It("errors, prints a tip and all warnings", func() { 204 Expect(executeErr).To(MatchError(translatableerror.TipDecoratorError{ 205 BaseError: errors.New("some-error"), 206 Tip: "A buildpack with name '{{.BuildpackName}}' and nil stack has been created. Use '{{.CfDeleteBuildpackCommand}}' to delete it or '{{.CfUpdateBuildpackCommand}}' to try again.", 207 TipKeys: map[string]interface{}{ 208 "BuildpackName": cmd.RequiredArgs.Buildpack, 209 "CfDeleteBuildpackCommand": cmd.Config.BinaryName() + " delete-buildpack", 210 "CfUpdateBuildpackCommand": cmd.Config.BinaryName() + " update-buildpack", 211 }, 212 })) 213 Expect(testUI.Err).To(Say("warning-2")) 214 Expect(testUI.Out).To(Say("Uploading buildpack %s", buildpackName)) 215 Consistently(testUI.Out).ShouldNot(Say("OK")) 216 }) 217 218 }) 219 220 When("Uploading the buildpack succeeds", func() { 221 BeforeEach(func() { 222 fakeActor.UploadBuildpackReturns( 223 ccv3.JobURL("http://example.com/some-job-url"), 224 v7action.Warnings{"some-upload-warning-1"}, 225 nil, 226 ) 227 }) 228 229 It("prints all warnings", func() { 230 Expect(executeErr).NotTo(HaveOccurred()) 231 Expect(testUI.Out).To(Say("Uploading buildpack %s", buildpackName)) 232 Expect(testUI.Out).To(Say("OK")) 233 Expect(testUI.Err).To(Say("some-upload-warning-1")) 234 235 Expect(fakeActor.UploadBuildpackCallCount()).To(Equal(1)) 236 guid, path, _ := fakeActor.UploadBuildpackArgsForCall(0) 237 Expect(guid).To(Equal("some-guid")) 238 Expect(path).To(Equal("buildpack.zip")) 239 }) 240 241 Describe("polling the upload-to-blobstore job", func() { 242 It("polls for job completion/failure", func() { 243 Expect(executeErr).NotTo(HaveOccurred()) 244 Expect(testUI.Out).To(Say("Uploading buildpack %s", buildpackName)) 245 Expect(testUI.Out).To(Say("OK")) 246 247 Expect(fakeActor.PollUploadBuildpackJobCallCount()).To(Equal(1)) 248 url := fakeActor.PollUploadBuildpackJobArgsForCall(0) 249 250 Expect(url).To(Equal(ccv3.JobURL("http://example.com/some-job-url"))) 251 }) 252 253 When("the job completes successfully", func() { 254 BeforeEach(func() { 255 fakeActor.PollUploadBuildpackJobReturns(v7action.Warnings{"poll-warning"}, nil) 256 }) 257 258 It("prints all warnings and exits successfully", func() { 259 Expect(executeErr).NotTo(HaveOccurred()) 260 Expect(testUI.Out).To(Say(`Processing uploaded buildpack %s\.\.\.`, buildpackName)) 261 Expect(testUI.Out).To(Say("OK")) 262 Expect(testUI.Err).To(Say("poll-warning")) 263 }) 264 }) 265 266 When("the job fails with an error", func() { 267 BeforeEach(func() { 268 fakeActor.PollUploadBuildpackJobReturns( 269 v7action.Warnings{"poll-warning"}, 270 errors.New("some-error"), 271 ) 272 }) 273 274 It("prints all warnings and a tip, then returns the error", func() { 275 Expect(executeErr).To(MatchError(translatableerror.TipDecoratorError{ 276 BaseError: errors.New("some-error"), 277 Tip: "A buildpack with name '{{.BuildpackName}}' and nil stack has been created. Use '{{.CfDeleteBuildpackCommand}}' to delete it or '{{.CfUpdateBuildpackCommand}}' to try again.", 278 TipKeys: map[string]interface{}{ 279 "BuildpackName": cmd.RequiredArgs.Buildpack, 280 "CfDeleteBuildpackCommand": cmd.Config.BinaryName() + " delete-buildpack", 281 "CfUpdateBuildpackCommand": cmd.Config.BinaryName() + " update-buildpack", 282 }, 283 })) 284 Expect(testUI.Err).To(Say("poll-warning")) 285 Expect(testUI.Out).To(Say(`Processing uploaded buildpack %s\.\.\.`, buildpackName)) 286 Consistently(testUI.Out).ShouldNot(Say("OK")) 287 }) 288 }) 289 }) 290 }) 291 }) 292 }) 293 }) 294 })