github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/command/v2/shared/get_application_changes_test.go (about) 1 package shared_test 2 3 import ( 4 "fmt" 5 6 "code.cloudfoundry.org/cli/actor/pushaction" 7 "code.cloudfoundry.org/cli/actor/v2action" 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant" 9 . "code.cloudfoundry.org/cli/command/v2/shared" 10 "code.cloudfoundry.org/cli/types" 11 "code.cloudfoundry.org/cli/util/ui" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/ginkgo/extensions/table" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("GetApplicationChanges", func() { 18 var ( 19 appName string 20 21 appConfig pushaction.ApplicationConfig 22 changes []ui.Change 23 ) 24 25 BeforeEach(func() { 26 appName = "steve" 27 28 appConfig = pushaction.ApplicationConfig{ 29 CurrentApplication: pushaction.Application{ 30 Application: v2action.Application{ 31 Name: appName, 32 StackGUID: "some-old-stack-guid", 33 }}, 34 DesiredApplication: pushaction.Application{ 35 Application: v2action.Application{ 36 Name: appName, 37 StackGUID: "some-new-stack-guid", 38 }}, 39 Path: "/foo/bar", 40 CurrentRoutes: []v2action.Route{ 41 {Host: "route1", Domain: v2action.Domain{Name: "example.com"}}, 42 {Host: "route2", Domain: v2action.Domain{Name: "example.com"}}, 43 }, 44 DesiredRoutes: []v2action.Route{ 45 {Host: "route3", Domain: v2action.Domain{Name: "example.com"}}, 46 {Host: "route4", Domain: v2action.Domain{Name: "example.com"}}, 47 }, 48 } 49 }) 50 51 JustBeforeEach(func() { 52 changes = GetApplicationChanges(appConfig) 53 }) 54 55 Describe("name", func() { 56 It("sets the first change to name", func() { 57 Expect(changes[0]).To(Equal(ui.Change{ 58 Header: "name:", 59 CurrentValue: appName, 60 NewValue: appName, 61 })) 62 }) 63 }) 64 65 Describe("docker image", func() { 66 BeforeEach(func() { 67 appConfig.CurrentApplication.DockerImage = "some-path" 68 appConfig.DesiredApplication.DockerImage = "some-new-path" 69 }) 70 71 It("set the second change to docker image", func() { 72 Expect(changes[1]).To(Equal(ui.Change{ 73 Header: "docker image:", 74 CurrentValue: "some-path", 75 NewValue: "some-new-path", 76 })) 77 }) 78 79 Describe("docker username", func() { 80 BeforeEach(func() { 81 appConfig.CurrentApplication.DockerCredentials.Username = "some-username" 82 appConfig.DesiredApplication.DockerCredentials.Username = "some-new-username" 83 }) 84 85 It("set the second change to docker image", func() { 86 Expect(changes[2]).To(Equal(ui.Change{ 87 Header: "docker username:", 88 CurrentValue: "some-username", 89 NewValue: "some-new-username", 90 })) 91 }) 92 }) 93 }) 94 95 Describe("path", func() { 96 It("sets the second change to path", func() { 97 Expect(changes[1]).To(Equal(ui.Change{ 98 Header: "path:", 99 CurrentValue: "/foo/bar", 100 NewValue: "/foo/bar", 101 })) 102 }) 103 }) 104 105 Describe("buildpack", func() { 106 Context("new app with no specified buildpack", func() { 107 It("does not provide a buildpack change", func() { 108 for i, change := range changes { 109 Expect(change.Header).ToNot(Equal("buildpack:"), fmt.Sprintf("entry %d should not be a buildpack", i)) 110 } 111 }) 112 }) 113 114 DescribeTable("non-empty values", 115 func( 116 currentBuildpack types.FilteredString, currentDetectedBuildpack types.FilteredString, 117 desiredBuildpack types.FilteredString, desiredDetectedBuildpack types.FilteredString, 118 currentValue string, newValue string, 119 ) { 120 appConfig.CurrentApplication.Buildpack = currentBuildpack 121 appConfig.CurrentApplication.DetectedBuildpack = currentDetectedBuildpack 122 appConfig.DesiredApplication.Buildpack = desiredBuildpack 123 appConfig.DesiredApplication.DetectedBuildpack = desiredDetectedBuildpack 124 125 changes = GetApplicationChanges(appConfig) 126 127 Expect(changes[2]).To(Equal(ui.Change{ 128 Header: "buildpack:", 129 CurrentValue: currentValue, 130 NewValue: newValue, 131 })) 132 }, 133 134 Entry("new app with buildpack specified", 135 types.FilteredString{}, types.FilteredString{}, 136 types.FilteredString{IsSet: true, Value: "some-new-buildpack"}, types.FilteredString{}, 137 "", "some-new-buildpack", 138 ), 139 Entry("existing buildpack with new buildpack specified", 140 types.FilteredString{IsSet: true, Value: "some-old-buildpack"}, types.FilteredString{}, 141 types.FilteredString{IsSet: true, Value: "some-new-buildpack"}, types.FilteredString{}, 142 "some-old-buildpack", "some-new-buildpack", 143 ), 144 Entry("existing detected buildpack with new buildpack specified", 145 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-buildpack"}, 146 types.FilteredString{IsSet: true, Value: "some-new-buildpack"}, types.FilteredString{}, 147 "some-detected-buildpack", "some-new-buildpack", 148 ), 149 Entry("existing detected buildpack with new detected buildpack", 150 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-buildpack"}, 151 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-buildpack"}, 152 "some-detected-buildpack", "some-detected-buildpack", 153 ), 154 155 // Can never happen because desired starts as a copy of current 156 Entry("existing buildpack with no new buildpack specified", 157 types.FilteredString{IsSet: true, Value: "some-old-buildpack"}, types.FilteredString{}, 158 types.FilteredString{}, types.FilteredString{}, 159 "some-old-buildpack", "", 160 ), 161 // Can never happen because desired starts as a copy of current 162 Entry("existing detected buildpack with no new buildpack specified", 163 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-buildpack"}, 164 types.FilteredString{}, types.FilteredString{}, 165 "some-detected-buildpack", "", 166 ), 167 ) 168 }) 169 170 Describe("command", func() { 171 Context("new app with no specified command", func() { 172 It("does not provide a command change", func() { 173 for i, change := range changes { 174 Expect(change.Header).ToNot(Equal("command:"), fmt.Sprintf("entry %d should not be command", i)) 175 } 176 }) 177 }) 178 179 DescribeTable("non-empty values", 180 func( 181 currentCommand types.FilteredString, currentDetectedCommand types.FilteredString, 182 desiredCommand types.FilteredString, desiredDetectedCommand types.FilteredString, 183 currentValue string, newValue string, 184 ) { 185 appConfig.CurrentApplication.Command = currentCommand 186 appConfig.CurrentApplication.DetectedStartCommand = currentDetectedCommand 187 appConfig.DesiredApplication.Command = desiredCommand 188 appConfig.DesiredApplication.DetectedStartCommand = desiredDetectedCommand 189 190 changes = GetApplicationChanges(appConfig) 191 192 Expect(changes[2]).To(Equal(ui.Change{ 193 Header: "command:", 194 CurrentValue: currentValue, 195 NewValue: newValue, 196 })) 197 }, 198 Entry("new app with command specified", 199 types.FilteredString{}, types.FilteredString{}, 200 types.FilteredString{IsSet: true, Value: "some-new-command"}, types.FilteredString{}, 201 "", "some-new-command", 202 ), 203 Entry("existing command with new command specified", 204 types.FilteredString{IsSet: true, Value: "some-old-command"}, types.FilteredString{}, 205 types.FilteredString{IsSet: true, Value: "some-new-command"}, types.FilteredString{}, 206 "some-old-command", "some-new-command", 207 ), 208 Entry("existing detected command with new command specified", 209 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"}, 210 types.FilteredString{IsSet: true, Value: "some-new-command"}, types.FilteredString{}, 211 "some-detected-command", "some-new-command", 212 ), 213 Entry("existing detected command with new detected command", 214 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"}, 215 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"}, 216 "some-detected-command", "some-detected-command", 217 ), 218 219 // Can never happen because desired starts as a copy of current 220 Entry("existing command with no new command specified", 221 types.FilteredString{IsSet: true, Value: "some-old-command"}, types.FilteredString{}, 222 types.FilteredString{}, types.FilteredString{}, 223 "some-old-command", "", 224 ), 225 // Can never happen because desired starts as a copy of current 226 Entry("existing detected command with no new command specified", 227 types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"}, 228 types.FilteredString{}, types.FilteredString{}, 229 "some-detected-command", "", 230 ), 231 ) 232 }) 233 234 Describe("disk_quota", func() { 235 Context("new app with no specified disk_quota", func() { 236 It("does not provide a disk_quota change", func() { 237 for i, change := range changes { 238 Expect(change.Header).ToNot(Equal("disk quota:"), fmt.Sprintf("entry %d should not be disk quota", i)) 239 } 240 }) 241 }) 242 243 DescribeTable("non-empty values", 244 func(existingDiskQuota int, newDiskQuota int, currentValue string, newValue string) { 245 appConfig.CurrentApplication.DiskQuota = types.NullByteSizeInMb{IsSet: existingDiskQuota != 0, Value: uint64(existingDiskQuota)} 246 appConfig.DesiredApplication.DiskQuota = types.NullByteSizeInMb{IsSet: true, Value: uint64(newDiskQuota)} 247 248 changes = GetApplicationChanges(appConfig) 249 250 Expect(changes[2]).To(Equal(ui.Change{ 251 Header: "disk quota:", 252 CurrentValue: currentValue, 253 NewValue: newValue, 254 })) 255 }, 256 Entry("new app with disk_quota specified", 0, 200, "", "200M"), 257 Entry("existing disk_quota with no disk_quota specified", 100, 0, "100M", "0"), 258 Entry("existing disk_quota with new disk_quota specified", 100, 200, "100M", "200M"), 259 ) 260 }) 261 262 Describe("health-check-http-endpoint", func() { 263 Context("new app with no specified health check http endpoint", func() { 264 It("does not provide an http endpoint check type change", func() { 265 for i, change := range changes { 266 Expect(change.Header).ToNot(Equal("health check http endpoint:"), fmt.Sprintf("entry %d should not be health check http endpoint", i)) 267 } 268 }) 269 }) 270 271 DescribeTable("non-empty values", 272 func(existingType string, newType string, currentValue string, newValue string) { 273 appConfig.CurrentApplication.HealthCheckHTTPEndpoint = existingType 274 appConfig.DesiredApplication.HealthCheckHTTPEndpoint = newType 275 276 changes = GetApplicationChanges(appConfig) 277 278 Expect(changes[2]).To(Equal(ui.Change{ 279 Header: "health check http endpoint:", 280 CurrentValue: currentValue, 281 NewValue: newValue, 282 })) 283 }, 284 Entry("new app with http-endpoint specified", "", "some-new-http-endpoint", "", "some-new-http-endpoint"), 285 Entry("existing http-endpoint with no http-endpoint specified", "some-old-http-endpoint", "", "some-old-http-endpoint", ""), 286 Entry("existing http-endpoint with new http-endpoint specified", "some-old-http-endpoint", "some-new-http-endpoint", "some-old-http-endpoint", "some-new-http-endpoint"), 287 ) 288 }) 289 290 Describe("health-check-timeout", func() { 291 Context("new app with no specified health check timeout", func() { 292 It("does not provide an health check timeout change", func() { 293 for i, change := range changes { 294 Expect(change.Header).ToNot(Equal("health check http endpoint:"), fmt.Sprintf("entry %d should not be health check http endpoint", i)) 295 } 296 }) 297 }) 298 299 DescribeTable("non-empty values", 300 func(existingTimeout int, newTimeout int, currentValue int, newValue int) { 301 appConfig.CurrentApplication.HealthCheckTimeout = existingTimeout 302 appConfig.DesiredApplication.HealthCheckTimeout = newTimeout 303 304 changes = GetApplicationChanges(appConfig) 305 306 Expect(changes[2]).To(Equal(ui.Change{ 307 Header: "health check timeout:", 308 CurrentValue: currentValue, 309 NewValue: newValue, 310 })) 311 }, 312 Entry("new app with health-check-timeout specified", 0, 200, 0, 200), 313 Entry("existing health-check-timeout with no health-check-timeout specified", 100, 0, 100, 0), 314 Entry("existing health-check-timeout with new health-check-timeout specified", 100, 200, 100, 200), 315 ) 316 }) 317 318 Describe("health-check-type", func() { 319 Context("new app with no specified health-check-type", func() { 320 It("does not provide a health check type change", func() { 321 for i, change := range changes { 322 Expect(change.Header).ToNot(Equal("health check type:"), fmt.Sprintf("entry %d should not be health check type", i)) 323 } 324 }) 325 }) 326 327 DescribeTable("non-empty values", 328 func(existingType constant.ApplicationHealthCheckType, newType constant.ApplicationHealthCheckType, currentValue string, newValue string) { 329 appConfig.CurrentApplication.HealthCheckType = existingType 330 appConfig.DesiredApplication.HealthCheckType = newType 331 332 changes = GetApplicationChanges(appConfig) 333 334 Expect(changes[2]).To(Equal(ui.Change{ 335 Header: "health check type:", 336 CurrentValue: currentValue, 337 NewValue: newValue, 338 })) 339 }, 340 Entry("new app with health-check-type specified", constant.ApplicationHealthCheckType(""), constant.ApplicationHealthCheckType("some-new-health-check-type"), "", "some-new-health-check-type"), 341 Entry("existing health-check-type with no health-check-type specified", constant.ApplicationHealthCheckType("some-old-health-check-type"), constant.ApplicationHealthCheckType(""), "some-old-health-check-type", ""), 342 Entry("existing health-check-type with new health-check-type specified", constant.ApplicationHealthCheckType("some-old-health-check-type"), constant.ApplicationHealthCheckType("some-new-health-check-type"), "some-old-health-check-type", "some-new-health-check-type"), 343 ) 344 }) 345 346 Describe("instances", func() { 347 Context("new app with no specified instances", func() { 348 It("does not provide an instances change", func() { 349 for i, change := range changes { 350 Expect(change.Header).ToNot(Equal("instances:"), fmt.Sprintf("entry %d should not be instances", i)) 351 } 352 }) 353 }) 354 355 DescribeTable("non-empty values", 356 func(existingInstances types.NullInt, newInstances types.NullInt, currentValue types.NullInt, newValue types.NullInt) { 357 appConfig.CurrentApplication.Instances = existingInstances 358 appConfig.DesiredApplication.Instances = newInstances 359 360 changes = GetApplicationChanges(appConfig) 361 362 Expect(changes[2]).To(Equal(ui.Change{ 363 Header: "instances:", 364 CurrentValue: currentValue, 365 NewValue: newValue, 366 })) 367 }, 368 Entry("new app with instances specified", types.NullInt{IsSet: false}, types.NullInt{Value: 200, IsSet: true}, types.NullInt{IsSet: false}, types.NullInt{Value: 200, IsSet: true}), 369 Entry("existing instances with new instances specified", types.NullInt{Value: 100, IsSet: true}, types.NullInt{Value: 0, IsSet: true}, types.NullInt{Value: 100, IsSet: true}, types.NullInt{Value: 0, IsSet: true}), 370 ) 371 }) 372 373 Describe("memory", func() { 374 Context("new app with no specified memory", func() { 375 It("does not provide a memory change", func() { 376 for i, change := range changes { 377 Expect(change.Header).ToNot(Equal("memory:"), fmt.Sprintf("entry %d should not be memory", i)) 378 } 379 }) 380 }) 381 382 DescribeTable("non-empty values", 383 func(existingMemory int, newMemory int, currentValue string, newValue string) { 384 appConfig.CurrentApplication.Memory = types.NullByteSizeInMb{IsSet: existingMemory != 0, Value: uint64(existingMemory)} 385 appConfig.DesiredApplication.Memory = types.NullByteSizeInMb{IsSet: true, Value: uint64(newMemory)} 386 387 changes = GetApplicationChanges(appConfig) 388 389 Expect(changes[2]).To(Equal(ui.Change{ 390 Header: "memory:", 391 CurrentValue: currentValue, 392 NewValue: newValue, 393 })) 394 }, 395 Entry("new app with memory specified", 0, 200, "", "200M"), 396 Entry("existing memory with no memory specified", 100, 0, "100M", "0"), 397 Entry("existing memory with new memory specified", 100, 200, "100M", "200M"), 398 ) 399 }) 400 401 Describe("stack", func() { 402 Context("new app with no specified stack", func() { 403 It("does not provide an stack change", func() { 404 for i, change := range changes { 405 Expect(change.Header).ToNot(Equal("stack:"), fmt.Sprintf("entry %d should not be stack", i)) 406 } 407 }) 408 }) 409 410 DescribeTable("non-empty values", 411 func(existingStack string, newStack string, currentValue string, newValue string) { 412 appConfig.CurrentApplication.Stack.Name = existingStack 413 appConfig.DesiredApplication.Stack.Name = newStack 414 415 changes = GetApplicationChanges(appConfig) 416 417 Expect(changes[2]).To(Equal(ui.Change{ 418 Header: "stack:", 419 CurrentValue: currentValue, 420 NewValue: newValue, 421 })) 422 }, 423 Entry("new app with stack specified", "", "some-new-stack", "", "some-new-stack"), 424 Entry("existing stack with no stack specified", "some-old-stack", "", "some-old-stack", ""), 425 Entry("existing stack with new stack specified", "some-old-stack", "some-new-stack", "some-old-stack", "some-new-stack"), 426 ) 427 }) 428 429 Describe("services", func() { 430 BeforeEach(func() { 431 appConfig.CurrentServices = map[string]v2action.ServiceInstance{"service-1": {}, "service-2": {}} 432 appConfig.DesiredServices = map[string]v2action.ServiceInstance{"service-3": {}, "service-4": {}} 433 }) 434 435 It("sets the third change to services", func() { 436 Expect(len(changes)).To(BeNumerically(">=", 2)) 437 change := changes[2] 438 Expect(change.Header).To(Equal("services:")) 439 Expect(change.CurrentValue).To(ConsistOf([]string{"service-1", "service-2"})) 440 Expect(change.NewValue).To(ConsistOf([]string{"service-3", "service-4"})) 441 }) 442 }) 443 444 Context("user provided environment variables", func() { 445 var oldMap, newMap map[string]string 446 447 BeforeEach(func() { 448 oldMap = map[string]string{"a": "b"} 449 newMap = map[string]string{"1": "2"} 450 appConfig.CurrentApplication.EnvironmentVariables = oldMap 451 appConfig.DesiredApplication.EnvironmentVariables = newMap 452 }) 453 454 It("sets the fourth change to routes", func() { 455 Expect(changes[3]).To(Equal(ui.Change{ 456 Header: "env:", 457 CurrentValue: oldMap, 458 NewValue: newMap, 459 })) 460 }) 461 }) 462 463 Describe("routes", func() { 464 It("sets the fifth change to routes", func() { 465 Expect(changes[4]).To(Equal(ui.Change{ 466 Header: "routes:", 467 CurrentValue: []string{"route1.example.com", "route2.example.com"}, 468 NewValue: []string{"route3.example.com", "route4.example.com"}, 469 })) 470 }) 471 }) 472 })