github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v6/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/v6/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("buildpacks", func() {
   106  		Context("new app with no specified buildpack AND no specified buildpacks(plural)", func() {
   107  			It("does not provide a buildpack change", func() {
   108  				for i, change := range changes {
   109  					Expect(change.Header).ToNot(Equal("buildpacks:"), fmt.Sprintf("entry %d should not be a buildpack", i))
   110  				}
   111  			})
   112  		})
   113  
   114  		DescribeTable("non-empty values",
   115  			func(
   116  				currentBuildpacks []string, desiredBuildpacks []string,
   117  			) {
   118  				appConfig.CurrentApplication.Buildpacks = currentBuildpacks
   119  				appConfig.DesiredApplication.Buildpacks = desiredBuildpacks
   120  
   121  				changes = GetApplicationChanges(appConfig)
   122  
   123  				Expect(changes[2]).To(Equal(ui.Change{
   124  					Header:       "buildpacks:",
   125  					CurrentValue: currentBuildpacks,
   126  					NewValue:     desiredBuildpacks,
   127  				}))
   128  			},
   129  
   130  			Entry("new app with buildpack specified", nil, []string{"buildpack-1", "buildpack-2"}),
   131  			Entry("existing app with buildpack specified", []string{"buildpack-1"}, []string{"buildpack-1", "buildpack-2"}),
   132  			Entry("existing app with forcing auto-detection", []string{"buildpack-1"}, nil),
   133  		)
   134  	})
   135  
   136  	Describe("command", func() {
   137  		Context("new app with no specified command", func() {
   138  			It("does not provide a command change", func() {
   139  				for i, change := range changes {
   140  					Expect(change.Header).ToNot(Equal("command:"), fmt.Sprintf("entry %d should not be command", i))
   141  				}
   142  			})
   143  		})
   144  
   145  		DescribeTable("non-empty values",
   146  			func(
   147  				currentCommand types.FilteredString, currentDetectedCommand types.FilteredString,
   148  				desiredCommand types.FilteredString, desiredDetectedCommand types.FilteredString,
   149  				currentValue string, newValue string,
   150  			) {
   151  				appConfig.CurrentApplication.Command = currentCommand
   152  				appConfig.CurrentApplication.DetectedStartCommand = currentDetectedCommand
   153  				appConfig.DesiredApplication.Command = desiredCommand
   154  				appConfig.DesiredApplication.DetectedStartCommand = desiredDetectedCommand
   155  
   156  				changes = GetApplicationChanges(appConfig)
   157  
   158  				Expect(changes[2]).To(Equal(ui.Change{
   159  					Header:       "command:",
   160  					CurrentValue: currentValue,
   161  					NewValue:     newValue,
   162  				}))
   163  			},
   164  			Entry("new app with command specified",
   165  				types.FilteredString{}, types.FilteredString{},
   166  				types.FilteredString{IsSet: true, Value: "some-new-command"}, types.FilteredString{},
   167  				"", "some-new-command",
   168  			),
   169  			Entry("existing command with new command specified",
   170  				types.FilteredString{IsSet: true, Value: "some-old-command"}, types.FilteredString{},
   171  				types.FilteredString{IsSet: true, Value: "some-new-command"}, types.FilteredString{},
   172  				"some-old-command", "some-new-command",
   173  			),
   174  			Entry("existing detected command with new command specified",
   175  				types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"},
   176  				types.FilteredString{IsSet: true, Value: "some-new-command"}, types.FilteredString{},
   177  				"some-detected-command", "some-new-command",
   178  			),
   179  			Entry("existing detected command with new detected command",
   180  				types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"},
   181  				types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"},
   182  				"some-detected-command", "some-detected-command",
   183  			),
   184  
   185  			// Can never happen because desired starts as a copy of current
   186  			Entry("existing command with no new command specified",
   187  				types.FilteredString{IsSet: true, Value: "some-old-command"}, types.FilteredString{},
   188  				types.FilteredString{}, types.FilteredString{},
   189  				"some-old-command", "",
   190  			),
   191  			// Can never happen because desired starts as a copy of current
   192  			Entry("existing detected command with no new command specified",
   193  				types.FilteredString{}, types.FilteredString{IsSet: true, Value: "some-detected-command"},
   194  				types.FilteredString{}, types.FilteredString{},
   195  				"some-detected-command", "",
   196  			),
   197  		)
   198  	})
   199  
   200  	Describe("disk_quota", func() {
   201  		Context("new app with no specified disk_quota", func() {
   202  			It("does not provide a disk_quota change", func() {
   203  				for i, change := range changes {
   204  					Expect(change.Header).ToNot(Equal("disk quota:"), fmt.Sprintf("entry %d should not be disk quota", i))
   205  				}
   206  			})
   207  		})
   208  
   209  		DescribeTable("non-empty values",
   210  			func(existingDiskQuota int, newDiskQuota int, currentValue string, newValue string) {
   211  				appConfig.CurrentApplication.DiskQuota = types.NullByteSizeInMb{IsSet: existingDiskQuota != 0, Value: uint64(existingDiskQuota)}
   212  				appConfig.DesiredApplication.DiskQuota = types.NullByteSizeInMb{IsSet: true, Value: uint64(newDiskQuota)}
   213  
   214  				changes = GetApplicationChanges(appConfig)
   215  
   216  				Expect(changes[2]).To(Equal(ui.Change{
   217  					Header:       "disk quota:",
   218  					CurrentValue: currentValue,
   219  					NewValue:     newValue,
   220  				}))
   221  			},
   222  			Entry("new app with disk_quota specified", 0, 200, "", "200M"),
   223  			Entry("existing disk_quota with no disk_quota specified", 100, 0, "100M", "0"),
   224  			Entry("existing disk_quota with new disk_quota specified", 100, 200, "100M", "200M"),
   225  		)
   226  	})
   227  
   228  	Describe("health-check-http-endpoint", func() {
   229  		Context("new app with no specified health check http endpoint", func() {
   230  			It("does not provide an http endpoint check type change", func() {
   231  				for i, change := range changes {
   232  					Expect(change.Header).ToNot(Equal("health check http endpoint:"), fmt.Sprintf("entry %d should not be health check http endpoint", i))
   233  				}
   234  			})
   235  		})
   236  
   237  		DescribeTable("non-empty values",
   238  			func(existingType string, newType string, currentValue string, newValue string) {
   239  				appConfig.CurrentApplication.HealthCheckHTTPEndpoint = existingType
   240  				appConfig.DesiredApplication.HealthCheckHTTPEndpoint = newType
   241  
   242  				changes = GetApplicationChanges(appConfig)
   243  
   244  				Expect(changes[2]).To(Equal(ui.Change{
   245  					Header:       "health check http endpoint:",
   246  					CurrentValue: currentValue,
   247  					NewValue:     newValue,
   248  				}))
   249  			},
   250  			Entry("new app with http-endpoint specified", "", "some-new-http-endpoint", "", "some-new-http-endpoint"),
   251  			Entry("existing http-endpoint with no http-endpoint specified", "some-old-http-endpoint", "", "some-old-http-endpoint", ""),
   252  			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"),
   253  		)
   254  	})
   255  
   256  	Describe("health-check-timeout", func() {
   257  		Context("new app with no specified health check timeout", func() {
   258  			It("does not provide an health check timeout change", func() {
   259  				for i, change := range changes {
   260  					Expect(change.Header).ToNot(Equal("health check http endpoint:"), fmt.Sprintf("entry %d should not be health check http endpoint", i))
   261  				}
   262  			})
   263  		})
   264  
   265  		DescribeTable("non-empty values",
   266  			func(existingTimeout int, newTimeout int, currentValue int, newValue int) {
   267  				appConfig.CurrentApplication.HealthCheckTimeout = uint64(existingTimeout)
   268  				appConfig.DesiredApplication.HealthCheckTimeout = uint64(newTimeout)
   269  
   270  				changes = GetApplicationChanges(appConfig)
   271  
   272  				Expect(changes[2]).To(Equal(ui.Change{
   273  					Header:       "health check timeout:",
   274  					CurrentValue: uint64(currentValue),
   275  					NewValue:     uint64(newValue),
   276  				}))
   277  			},
   278  			Entry("new app with health-check-timeout specified", 0, 200, 0, 200),
   279  			Entry("existing health-check-timeout with no health-check-timeout specified", 100, 0, 100, 0),
   280  			Entry("existing health-check-timeout with new health-check-timeout specified", 100, 200, 100, 200),
   281  		)
   282  	})
   283  
   284  	Describe("health-check-type", func() {
   285  		Context("new app with no specified health-check-type", func() {
   286  			It("does not provide a health check type change", func() {
   287  				for i, change := range changes {
   288  					Expect(change.Header).ToNot(Equal("health check type:"), fmt.Sprintf("entry %d should not be health check type", i))
   289  				}
   290  			})
   291  		})
   292  
   293  		DescribeTable("non-empty values",
   294  			func(existingType constant.ApplicationHealthCheckType, newType constant.ApplicationHealthCheckType, currentValue string, newValue string) {
   295  				appConfig.CurrentApplication.HealthCheckType = existingType
   296  				appConfig.DesiredApplication.HealthCheckType = newType
   297  
   298  				changes = GetApplicationChanges(appConfig)
   299  
   300  				Expect(changes[2]).To(Equal(ui.Change{
   301  					Header:       "health check type:",
   302  					CurrentValue: currentValue,
   303  					NewValue:     newValue,
   304  				}))
   305  			},
   306  			Entry("new app with health-check-type specified", constant.ApplicationHealthCheckType(""), constant.ApplicationHealthCheckType("some-new-health-check-type"), "", "some-new-health-check-type"),
   307  			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", ""),
   308  			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"),
   309  		)
   310  	})
   311  
   312  	Describe("instances", func() {
   313  		Context("new app with no specified instances", func() {
   314  			It("does not provide an instances change", func() {
   315  				for i, change := range changes {
   316  					Expect(change.Header).ToNot(Equal("instances:"), fmt.Sprintf("entry %d should not be instances", i))
   317  				}
   318  			})
   319  		})
   320  
   321  		DescribeTable("non-empty values",
   322  			func(existingInstances types.NullInt, newInstances types.NullInt, currentValue types.NullInt, newValue types.NullInt) {
   323  				appConfig.CurrentApplication.Instances = existingInstances
   324  				appConfig.DesiredApplication.Instances = newInstances
   325  
   326  				changes = GetApplicationChanges(appConfig)
   327  
   328  				Expect(changes[2]).To(Equal(ui.Change{
   329  					Header:       "instances:",
   330  					CurrentValue: currentValue,
   331  					NewValue:     newValue,
   332  				}))
   333  			},
   334  			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}),
   335  			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}),
   336  		)
   337  	})
   338  
   339  	Describe("memory", func() {
   340  		Context("new app with no specified memory", func() {
   341  			It("does not provide a memory change", func() {
   342  				for i, change := range changes {
   343  					Expect(change.Header).ToNot(Equal("memory:"), fmt.Sprintf("entry %d should not be memory", i))
   344  				}
   345  			})
   346  		})
   347  
   348  		DescribeTable("non-empty values",
   349  			func(existingMemory int, newMemory int, currentValue string, newValue string) {
   350  				appConfig.CurrentApplication.Memory = types.NullByteSizeInMb{IsSet: existingMemory != 0, Value: uint64(existingMemory)}
   351  				appConfig.DesiredApplication.Memory = types.NullByteSizeInMb{IsSet: true, Value: uint64(newMemory)}
   352  
   353  				changes = GetApplicationChanges(appConfig)
   354  
   355  				Expect(changes[2]).To(Equal(ui.Change{
   356  					Header:       "memory:",
   357  					CurrentValue: currentValue,
   358  					NewValue:     newValue,
   359  				}))
   360  			},
   361  			Entry("new app with memory specified", 0, 200, "", "200M"),
   362  			Entry("existing memory with no memory specified", 100, 0, "100M", "0"),
   363  			Entry("existing memory with new memory specified", 100, 200, "100M", "200M"),
   364  		)
   365  	})
   366  
   367  	Describe("stack", func() {
   368  		Context("new app with no specified stack", func() {
   369  			It("does not provide an stack change", func() {
   370  				for i, change := range changes {
   371  					Expect(change.Header).ToNot(Equal("stack:"), fmt.Sprintf("entry %d should not be stack", i))
   372  				}
   373  			})
   374  		})
   375  
   376  		DescribeTable("non-empty values",
   377  			func(existingStack string, newStack string, currentValue string, newValue string) {
   378  				appConfig.CurrentApplication.Stack.Name = existingStack
   379  				appConfig.DesiredApplication.Stack.Name = newStack
   380  
   381  				changes = GetApplicationChanges(appConfig)
   382  
   383  				Expect(changes[2]).To(Equal(ui.Change{
   384  					Header:       "stack:",
   385  					CurrentValue: currentValue,
   386  					NewValue:     newValue,
   387  				}))
   388  			},
   389  			Entry("new app with stack specified", "", "some-new-stack", "", "some-new-stack"),
   390  			Entry("existing stack with no stack specified", "some-old-stack", "", "some-old-stack", ""),
   391  			Entry("existing stack with new stack specified", "some-old-stack", "some-new-stack", "some-old-stack", "some-new-stack"),
   392  		)
   393  	})
   394  
   395  	Describe("services", func() {
   396  		BeforeEach(func() {
   397  			appConfig.CurrentServices = map[string]v2action.ServiceInstance{"service-1": {}, "service-2": {}}
   398  			appConfig.DesiredServices = map[string]v2action.ServiceInstance{"service-3": {}, "service-4": {}}
   399  		})
   400  
   401  		It("sets the third change to services", func() {
   402  			Expect(len(changes)).To(BeNumerically(">=", 2))
   403  			change := changes[2]
   404  			Expect(change.Header).To(Equal("services:"))
   405  			Expect(change.CurrentValue).To(ConsistOf([]string{"service-1", "service-2"}))
   406  			Expect(change.NewValue).To(ConsistOf([]string{"service-3", "service-4"}))
   407  		})
   408  	})
   409  
   410  	Context("user provided environment variables", func() {
   411  		var oldMap, newMap map[string]string
   412  
   413  		BeforeEach(func() {
   414  			oldMap = map[string]string{"a": "b"}
   415  			newMap = map[string]string{"1": "2"}
   416  			appConfig.CurrentApplication.EnvironmentVariables = oldMap
   417  			appConfig.DesiredApplication.EnvironmentVariables = newMap
   418  		})
   419  
   420  		It("sets the fourth change to routes", func() {
   421  			Expect(changes[3]).To(Equal(ui.Change{
   422  				Header:       "env:",
   423  				CurrentValue: oldMap,
   424  				NewValue:     newMap,
   425  			}))
   426  		})
   427  	})
   428  
   429  	Describe("routes", func() {
   430  		It("sets the fifth change to routes", func() {
   431  			Expect(changes[4]).To(Equal(ui.Change{
   432  				Header:       "routes:",
   433  				CurrentValue: []string{"route1.example.com", "route2.example.com"},
   434  				NewValue:     []string{"route3.example.com", "route4.example.com"},
   435  			}))
   436  		})
   437  	})
   438  })