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  })