github.com/swisscom/cloudfoundry-cli@v7.1.0+incompatible/cf/commands/application/app_test.go (about)

     1  package application_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"time"
     6  
     7  	"code.cloudfoundry.org/cli/cf/api"
     8  	"code.cloudfoundry.org/cli/cf/api/resources"
     9  	"code.cloudfoundry.org/cli/cf/api/stacks/stacksfakes"
    10  	"code.cloudfoundry.org/cli/cf/commandregistry"
    11  	"code.cloudfoundry.org/cli/cf/commands/application"
    12  	"code.cloudfoundry.org/cli/cf/errors"
    13  	"code.cloudfoundry.org/cli/cf/flags"
    14  	"code.cloudfoundry.org/cli/cf/formatters"
    15  	"code.cloudfoundry.org/cli/cf/models"
    16  	"code.cloudfoundry.org/cli/cf/requirements"
    17  	"code.cloudfoundry.org/cli/cf/requirements/requirementsfakes"
    18  	"code.cloudfoundry.org/cli/plugin/models"
    19  
    20  	testconfig "code.cloudfoundry.org/cli/cf/util/testhelpers/configuration"
    21  	testterm "code.cloudfoundry.org/cli/cf/util/testhelpers/terminal"
    22  
    23  	"code.cloudfoundry.org/cli/cf/api/apifakes"
    24  	"code.cloudfoundry.org/cli/cf/api/appinstances/appinstancesfakes"
    25  
    26  	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
    27  
    28  	. "github.com/onsi/ginkgo"
    29  	. "github.com/onsi/gomega"
    30  )
    31  
    32  var _ = Describe("App", func() {
    33  	var (
    34  		ui               *testterm.FakeUI
    35  		appSummaryRepo   *apifakes.FakeAppSummaryRepository
    36  		appInstancesRepo *appinstancesfakes.FakeAppInstancesRepository
    37  		stackRepo        *stacksfakes.FakeStackRepository
    38  		getAppModel      *plugin_models.GetAppModel
    39  
    40  		cmd         commandregistry.Command
    41  		deps        commandregistry.Dependency
    42  		factory     *requirementsfakes.FakeFactory
    43  		flagContext flags.FlagContext
    44  
    45  		loginRequirement         requirements.Requirement
    46  		targetedSpaceRequirement requirements.Requirement
    47  		applicationRequirement   *requirementsfakes.FakeApplicationRequirement
    48  	)
    49  
    50  	BeforeEach(func() {
    51  		cmd = &application.ShowApp{}
    52  		flagContext = flags.NewFlagContext(cmd.MetaData().Flags)
    53  
    54  		ui = &testterm.FakeUI{}
    55  
    56  		getAppModel = &plugin_models.GetAppModel{}
    57  
    58  		repoLocator := api.RepositoryLocator{}
    59  		appSummaryRepo = new(apifakes.FakeAppSummaryRepository)
    60  		repoLocator = repoLocator.SetAppSummaryRepository(appSummaryRepo)
    61  		appInstancesRepo = new(appinstancesfakes.FakeAppInstancesRepository)
    62  		repoLocator = repoLocator.SetAppInstancesRepository(appInstancesRepo)
    63  		stackRepo = new(stacksfakes.FakeStackRepository)
    64  		repoLocator = repoLocator.SetStackRepository(stackRepo)
    65  
    66  		deps = commandregistry.Dependency{
    67  			UI:     ui,
    68  			Config: testconfig.NewRepositoryWithDefaults(),
    69  			PluginModels: &commandregistry.PluginModels{
    70  				Application: getAppModel,
    71  			},
    72  			RepoLocator: repoLocator,
    73  		}
    74  
    75  		cmd.SetDependency(deps, false)
    76  
    77  		factory = new(requirementsfakes.FakeFactory)
    78  
    79  		loginRequirement = &passingRequirement{}
    80  		factory.NewLoginRequirementReturns(loginRequirement)
    81  
    82  		targetedSpaceRequirement = &passingRequirement{}
    83  		factory.NewTargetedSpaceRequirementReturns(targetedSpaceRequirement)
    84  
    85  		applicationRequirement = new(requirementsfakes.FakeApplicationRequirement)
    86  		factory.NewApplicationRequirementReturns(applicationRequirement)
    87  	})
    88  
    89  	Describe("Requirements", func() {
    90  		Context("when not provided exactly one arg", func() {
    91  			BeforeEach(func() {
    92  				flagContext.Parse("app-name", "extra-arg")
    93  			})
    94  
    95  			It("fails with usage", func() {
    96  				_, err := cmd.Requirements(factory, flagContext)
    97  				Expect(err).To(HaveOccurred())
    98  				Expect(ui.Outputs()).To(ContainSubstrings(
    99  					[]string{"Incorrect Usage. Requires an argument"},
   100  					[]string{"NAME"},
   101  					[]string{"USAGE"},
   102  				))
   103  			})
   104  		})
   105  
   106  		Context("when provided exactly one arg", func() {
   107  			BeforeEach(func() {
   108  				flagContext.Parse("app-name")
   109  			})
   110  
   111  			It("returns a LoginRequirement", func() {
   112  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   113  				Expect(err).NotTo(HaveOccurred())
   114  				Expect(factory.NewLoginRequirementCallCount()).To(Equal(1))
   115  
   116  				Expect(actualRequirements).To(ContainElement(loginRequirement))
   117  			})
   118  
   119  			It("returns a TargetedSpaceRequirement", func() {
   120  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   121  				Expect(err).NotTo(HaveOccurred())
   122  				Expect(factory.NewTargetedSpaceRequirementCallCount()).To(Equal(1))
   123  
   124  				Expect(actualRequirements).To(ContainElement(targetedSpaceRequirement))
   125  			})
   126  
   127  			It("returns an ApplicationRequirement", func() {
   128  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   129  				Expect(err).NotTo(HaveOccurred())
   130  				Expect(factory.NewApplicationRequirementCallCount()).To(Equal(1))
   131  				Expect(factory.NewApplicationRequirementArgsForCall(0)).To(Equal("app-name"))
   132  
   133  				Expect(actualRequirements).To(ContainElement(applicationRequirement))
   134  			})
   135  		})
   136  	})
   137  
   138  	Describe("Execute", func() {
   139  		var (
   140  			getApplicationModel models.Application
   141  			getAppSummaryModel  models.Application
   142  			appStackModel       models.Stack
   143  			appInstanceFields   []models.AppInstanceFields
   144  			getAppSummaryErr    error
   145  			err                 error
   146  		)
   147  
   148  		BeforeEach(func() {
   149  			err := flagContext.Parse("app-name")
   150  			Expect(err).NotTo(HaveOccurred())
   151  			cmd.Requirements(factory, flagContext)
   152  
   153  			paginatedApplicationResources := resources.PaginatedApplicationResources{}
   154  			err = json.Unmarshal([]byte(getApplicationJSON), &paginatedApplicationResources)
   155  			Expect(err).NotTo(HaveOccurred())
   156  
   157  			getApplicationModel = paginatedApplicationResources.Resources[0].ToModel()
   158  
   159  			applicationFromSummary := api.ApplicationFromSummary{}
   160  			err = json.Unmarshal([]byte(getSummaryJSON), &applicationFromSummary)
   161  			Expect(err).NotTo(HaveOccurred())
   162  
   163  			getAppSummaryModel = applicationFromSummary.ToModel()
   164  
   165  			appInstanceFields = []models.AppInstanceFields{
   166  				{
   167  					State:     models.InstanceRunning,
   168  					Details:   "fake-instance-details",
   169  					Since:     time.Date(2015, time.November, 19, 1, 1, 17, 0, time.UTC),
   170  					CPUUsage:  float64(0.25),
   171  					DiskUsage: int64(1 * formatters.GIGABYTE),
   172  					DiskQuota: int64(2 * formatters.GIGABYTE),
   173  					MemUsage:  int64(24 * formatters.MEGABYTE),
   174  					MemQuota:  int64(32 * formatters.MEGABYTE),
   175  				},
   176  			}
   177  
   178  			appStackModel = models.Stack{
   179  				GUID: "fake-stack-guid",
   180  				Name: "fake-stack-name",
   181  			}
   182  
   183  			applicationRequirement.GetApplicationReturns(getApplicationModel)
   184  			appSummaryRepo.GetSummaryReturns(getAppSummaryModel, getAppSummaryErr)
   185  			appInstancesRepo.GetInstancesReturns(appInstanceFields, nil)
   186  			stackRepo.FindByGUIDReturns(appStackModel, nil)
   187  		})
   188  
   189  		JustBeforeEach(func() {
   190  			err = cmd.Execute(flagContext)
   191  		})
   192  
   193  		It("gets the application summary", func() {
   194  			Expect(err).NotTo(HaveOccurred())
   195  			Expect(appSummaryRepo.GetSummaryCallCount()).To(Equal(1))
   196  		})
   197  
   198  		It("gets the app instances", func() {
   199  			Expect(err).NotTo(HaveOccurred())
   200  			Expect(appInstancesRepo.GetInstancesCallCount()).To(Equal(1))
   201  		})
   202  
   203  		It("gets the application from the application requirement", func() {
   204  			Expect(err).NotTo(HaveOccurred())
   205  			Expect(applicationRequirement.GetApplicationCallCount()).To(Equal(1))
   206  		})
   207  
   208  		It("gets the stack name from the stack repository", func() {
   209  			Expect(err).NotTo(HaveOccurred())
   210  			Expect(stackRepo.FindByGUIDCallCount()).To(Equal(1))
   211  		})
   212  
   213  		It("prints a summary of the app", func() {
   214  			Expect(err).NotTo(HaveOccurred())
   215  			Expect(ui.Outputs()).To(ContainSubstrings(
   216  				[]string{"Showing health and status for app fake-app-name"},
   217  				[]string{"requested state: started"},
   218  				[]string{"instances: 1/1"},
   219  				[]string{"usage: 1G x 1 instances"},
   220  				[]string{"urls: fake-route-host.fake-route-domain-name"},
   221  				[]string{"last uploaded: Thu Nov 19 01:00:15 UTC 2015"},
   222  				[]string{"stack: fake-stack-name"},
   223  				// buildpack tested separately
   224  				[]string{"#0", "running", "2015-11-19 01:01:17 AM", "25.0%", "24M of 32M", "1G of 2G"},
   225  			))
   226  		})
   227  
   228  		Context("when getting the application summary fails because the app is stopped", func() {
   229  			BeforeEach(func() {
   230  				getAppSummaryModel.RunningInstances = 0
   231  				getAppSummaryModel.InstanceCount = 1
   232  				getAppSummaryModel.State = "stopped"
   233  				appSummaryRepo.GetSummaryReturns(getAppSummaryModel, errors.NewHTTPError(400, errors.InstancesError, "error"))
   234  			})
   235  
   236  			It("prints appropriate output", func() {
   237  				Expect(err).NotTo(HaveOccurred())
   238  				Expect(ui.Outputs()).To(ContainSubstrings(
   239  					[]string{"Showing health and status", "fake-app-name", "my-org", "my-space", "my-user"},
   240  					[]string{"state", "stopped"},
   241  					[]string{"instances", "0/1"},
   242  					[]string{"usage", "1G x 1 instances"},
   243  					[]string{"There are no running instances of this app."},
   244  				))
   245  			})
   246  		})
   247  
   248  		Context("when getting the application summary fails because the app has not yet finished staged", func() {
   249  			BeforeEach(func() {
   250  				getAppSummaryModel.RunningInstances = 0
   251  				getAppSummaryModel.InstanceCount = 1
   252  				getAppSummaryModel.State = "stopped"
   253  				appSummaryRepo.GetSummaryReturns(getAppSummaryModel, errors.NewHTTPError(400, errors.NotStaged, "error"))
   254  			})
   255  
   256  			It("prints appropriate output", func() {
   257  				Expect(err).NotTo(HaveOccurred())
   258  				Expect(ui.Outputs()).To(ContainSubstrings(
   259  					[]string{"Showing health and status", "fake-app-name", "my-org", "my-space", "my-user"},
   260  					[]string{"state", "stopped"},
   261  					[]string{"instances", "0/1"},
   262  					[]string{"usage", "1G x 1 instances"},
   263  					[]string{"There are no running instances of this app."},
   264  				))
   265  			})
   266  		})
   267  
   268  		Context("when getting the application summary fails for any other reason", func() {
   269  			BeforeEach(func() {
   270  				getAppSummaryModel.RunningInstances = 0
   271  				getAppSummaryModel.InstanceCount = 1
   272  				appSummaryRepo.GetSummaryReturns(getAppSummaryModel, errors.New("an-error"))
   273  			})
   274  
   275  			It("returns an error", func() {
   276  				Expect(err).To(HaveOccurred())
   277  				Expect(err.Error()).To(Equal("an-error"))
   278  			})
   279  
   280  			Context("when the app is stopped", func() {
   281  				BeforeEach(func() {
   282  					getAppSummaryModel.State = "stopped"
   283  					appSummaryRepo.GetSummaryReturns(getAppSummaryModel, errors.New("an-error"))
   284  				})
   285  
   286  				It("prints appropriate output", func() {
   287  					Expect(err).NotTo(HaveOccurred())
   288  					Expect(ui.Outputs()).To(ContainSubstrings(
   289  						[]string{"Showing health and status", "fake-app-name", "my-org", "my-space", "my-user"},
   290  						[]string{"state", "stopped"},
   291  						[]string{"instances", "0/1"},
   292  						[]string{"usage", "1G x 1 instances"},
   293  						[]string{"There are no running instances of this app."},
   294  					))
   295  				})
   296  			})
   297  		})
   298  
   299  		Context("when getting the app instances fails", func() {
   300  			BeforeEach(func() {
   301  				appInstancesRepo.GetInstancesReturns([]models.AppInstanceFields{}, errors.New("an-error"))
   302  			})
   303  
   304  			It("returns an error", func() {
   305  				Expect(err).To(HaveOccurred())
   306  				Expect(err.Error()).To(Equal("an-error"))
   307  			})
   308  
   309  			Context("when the app is stopped", func() {
   310  				BeforeEach(func() {
   311  					getAppSummaryModel.RunningInstances = 0
   312  					getAppSummaryModel.State = "stopped"
   313  					appSummaryRepo.GetSummaryReturns(getAppSummaryModel, nil)
   314  				})
   315  
   316  				It("prints appropriate output", func() {
   317  					Expect(err).NotTo(HaveOccurred())
   318  					Expect(ui.Outputs()).To(ContainSubstrings(
   319  						[]string{"Showing health and status", "fake-app-name", "my-org", "my-space", "my-user"},
   320  						[]string{"state", "stopped"},
   321  						[]string{"instances", "0/1"},
   322  						[]string{"usage", "1G x 1 instances"},
   323  						[]string{"There are no running instances of this app."},
   324  					))
   325  				})
   326  			})
   327  		})
   328  
   329  		Context("when the package updated at is missing", func() {
   330  			BeforeEach(func() {
   331  				getAppSummaryModel.PackageUpdatedAt = nil
   332  				appSummaryRepo.GetSummaryReturns(getAppSummaryModel, nil)
   333  			})
   334  
   335  			It("prints 'unknown' as last uploaded", func() {
   336  				Expect(err).NotTo(HaveOccurred())
   337  
   338  				Expect(ui.Outputs()).To(ContainSubstrings(
   339  					[]string{"last uploaded: unknown"},
   340  				))
   341  			})
   342  		})
   343  
   344  		Context("when the GetApplication model includes a buildpack", func() {
   345  			// this should be the GetAppSummary model
   346  			BeforeEach(func() {
   347  				getApplicationModel.Buildpack = "fake-buildpack"
   348  				getApplicationModel.DetectedBuildpack = ""
   349  				applicationRequirement.GetApplicationReturns(getApplicationModel)
   350  			})
   351  
   352  			It("prints the buildpack", func() {
   353  				Expect(err).NotTo(HaveOccurred())
   354  
   355  				Expect(ui.Outputs()).To(ContainSubstrings(
   356  					[]string{"buildpack", "fake-buildpack"},
   357  				))
   358  			})
   359  		})
   360  
   361  		Context("when the GetApplication Model includes a detected buildpack", func() {
   362  			// this should be the GetAppSummary model
   363  			BeforeEach(func() {
   364  				getApplicationModel.Buildpack = ""
   365  				getApplicationModel.DetectedBuildpack = "fake-detected-buildpack"
   366  				applicationRequirement.GetApplicationReturns(getApplicationModel)
   367  			})
   368  
   369  			It("prints the detected buildpack", func() {
   370  				Expect(err).NotTo(HaveOccurred())
   371  
   372  				Expect(ui.Outputs()).To(ContainSubstrings(
   373  					[]string{"buildpack", "fake-detected-buildpack"},
   374  				))
   375  			})
   376  		})
   377  
   378  		Context("when the GetApplication Model does not include a buildpack or detected buildpack", func() {
   379  			// this should be the GetAppSummary model
   380  			BeforeEach(func() {
   381  				getApplicationModel.Buildpack = ""
   382  				getApplicationModel.DetectedBuildpack = ""
   383  				applicationRequirement.GetApplicationReturns(getApplicationModel)
   384  			})
   385  
   386  			It("prints the 'unknown' as the buildpack", func() {
   387  				Expect(err).NotTo(HaveOccurred())
   388  				Expect(ui.Outputs()).To(ContainSubstrings(
   389  					[]string{"buildpack", "unknown"},
   390  				))
   391  			})
   392  		})
   393  
   394  		Context("when running instances is -1", func() {
   395  			BeforeEach(func() {
   396  				getAppSummaryModel.RunningInstances = -1
   397  				appSummaryRepo.GetSummaryReturns(getAppSummaryModel, nil)
   398  			})
   399  
   400  			It("displays a '?' for running instances", func() {
   401  				Expect(err).NotTo(HaveOccurred())
   402  				Expect(ui.Outputs()).To(ContainSubstrings(
   403  					[]string{"instances", "?/1"},
   404  				))
   405  			})
   406  		})
   407  
   408  		Context("when the --guid flag is passed", func() {
   409  			BeforeEach(func() {
   410  				flagContext.Parse("app-name", "--guid")
   411  			})
   412  
   413  			It("only prints the guid for the app", func() {
   414  				Expect(err).NotTo(HaveOccurred())
   415  				Expect(ui.Outputs()).To(ContainSubstrings(
   416  					[]string{"fake-app-guid"},
   417  				))
   418  				Expect(ui.Outputs()).ToNot(ContainSubstrings(
   419  					[]string{"Showing health and status", "my-app"},
   420  				))
   421  			})
   422  		})
   423  
   424  		Context("when called from a plugin", func() {
   425  			BeforeEach(func() {
   426  				cmd.SetDependency(deps, true)
   427  			})
   428  
   429  			Context("when the app is running", func() {
   430  				It("populates the plugin model", func() {
   431  					Expect(err).NotTo(HaveOccurred())
   432  
   433  					// from AppRequirement model
   434  					Expect(getAppModel.Stack.Name).To(Equal("fake-stack-name"))
   435  					Expect(getAppModel.Stack.Guid).To(Equal("fake-stack-guid"))
   436  
   437  					// from GetAppSummary model
   438  					Expect(getAppModel.Name).To(Equal("fake-app-name"))
   439  					Expect(getAppModel.State).To(Equal("started"))
   440  					Expect(getAppModel.Guid).To(Equal("fake-app-guid"))
   441  					Expect(getAppModel.Command).To(Equal("fake-command"))
   442  					Expect(getAppModel.DetectedStartCommand).To(Equal("fake-detected-start-command"))
   443  					Expect(getAppModel.DiskQuota).To(Equal(int64(1024)))
   444  					Expect(getAppModel.EnvironmentVars).To(Equal(map[string]interface{}{"fake-env-var": "fake-env-var-value"}))
   445  					Expect(getAppModel.InstanceCount).To(Equal(1))
   446  					Expect(getAppModel.Memory).To(Equal(int64(1024)))
   447  					Expect(getAppModel.RunningInstances).To(Equal(1))
   448  					Expect(getAppModel.HealthCheckTimeout).To(Equal(0))
   449  					Expect(getAppModel.SpaceGuid).To(Equal("fake-space-guid"))
   450  					Expect(getAppModel.PackageUpdatedAt.String()).To(Equal(time.Date(2015, time.November, 19, 1, 0, 15, 0, time.UTC).String()))
   451  					Expect(getAppModel.PackageState).To(Equal("STAGED"))
   452  					Expect(getAppModel.StagingFailedReason).To(BeEmpty())
   453  					Expect(getAppModel.BuildpackUrl).To(Equal("fake-buildpack"))
   454  					Expect(getAppModel.Routes[0].Host).To(Equal("fake-route-host"))
   455  					Expect(getAppModel.Routes[0].Guid).To(Equal("fake-route-guid"))
   456  					Expect(getAppModel.Routes[0].Domain.Name).To(Equal("fake-route-domain-name"))
   457  					Expect(getAppModel.Routes[0].Domain.Guid).To(Equal("fake-route-domain-guid"))
   458  					Expect(getAppModel.Routes[0].Path).To(Equal("some-path"))
   459  					Expect(getAppModel.Routes[0].Port).To(Equal(3333))
   460  					Expect(getAppModel.Services[0].Guid).To(Equal("fake-service-guid"))
   461  					Expect(getAppModel.Services[0].Name).To(Equal("fake-service-name"))
   462  
   463  					// from GetInstances model
   464  					Expect(getAppModel.Instances[0].State).To(Equal("running"))
   465  					Expect(getAppModel.Instances[0].Details).To(Equal("fake-instance-details"))
   466  					Expect(getAppModel.Instances[0].CpuUsage).To(Equal(float64(0.25)))
   467  					Expect(getAppModel.Instances[0].DiskUsage).To(Equal(int64(1 * formatters.GIGABYTE)))
   468  					Expect(getAppModel.Instances[0].DiskQuota).To(Equal(int64(2 * formatters.GIGABYTE)))
   469  					Expect(getAppModel.Instances[0].MemUsage).To(Equal(int64(24 * formatters.MEGABYTE)))
   470  					Expect(getAppModel.Instances[0].MemQuota).To(Equal(int64(32 * formatters.MEGABYTE)))
   471  				})
   472  			})
   473  
   474  			Context("when the app is stopped but instance is returning back an error", func() {
   475  				BeforeEach(func() {
   476  					getAppSummaryModel.State = "stopped"
   477  					appSummaryRepo.GetSummaryReturns(getAppSummaryModel, nil)
   478  
   479  					var instances []models.AppInstanceFields //Very important since this is a nil body
   480  					appInstancesRepo.GetInstancesReturns(instances, errors.New("Bonzi"))
   481  				})
   482  
   483  				It("populates the plugin model with empty sets", func() {
   484  					Expect(err).NotTo(HaveOccurred())
   485  
   486  					Expect(getAppModel.Instances).ToNot(BeNil())
   487  					Expect(getAppModel.Instances).To(BeEmpty())
   488  				})
   489  			})
   490  
   491  			Context("when the there are no routes", func() {
   492  				BeforeEach(func() {
   493  					app := models.Application{
   494  						Stack: &models.Stack{
   495  							GUID: "stack-guid",
   496  							Name: "stack-name",
   497  						},
   498  					}
   499  					appSummaryRepo.GetSummaryReturns(app, nil)
   500  				})
   501  
   502  				It("populates the plugin model with empty sets", func() {
   503  					Expect(err).NotTo(HaveOccurred())
   504  
   505  					Expect(getAppModel.Routes).ToNot(BeNil())
   506  					Expect(getAppModel.Routes).To(BeEmpty())
   507  				})
   508  			})
   509  
   510  			Context("when the there are no services", func() {
   511  				BeforeEach(func() {
   512  					app := models.Application{
   513  						Stack: &models.Stack{
   514  							GUID: "stack-guid",
   515  							Name: "stack-name",
   516  						},
   517  					}
   518  					appSummaryRepo.GetSummaryReturns(app, nil)
   519  				})
   520  
   521  				It("populates the plugin model with empty sets", func() {
   522  					Expect(err).NotTo(HaveOccurred())
   523  
   524  					Expect(getAppModel.Services).ToNot(BeNil())
   525  					Expect(getAppModel.Services).To(BeEmpty())
   526  				})
   527  			})
   528  		})
   529  	})
   530  })
   531  
   532  var getApplicationJSON string = `{
   533    "total_results": 1,
   534    "total_pages": 1,
   535    "prev_url": null,
   536    "next_url": null,
   537    "resources": [
   538      {
   539        "metadata": {
   540          "guid": "fake-app-guid",
   541          "url": "fake-url",
   542          "created_at": "2015-11-19T01:00:12Z",
   543          "updated_at": "2015-11-19T01:01:04Z"
   544        },
   545        "entity": {
   546          "name": "fake-app-name",
   547          "production": false,
   548          "space_guid": "fake-space-guid",
   549          "stack_guid": "fake-stack-guid",
   550          "buildpack": null,
   551          "detected_buildpack": "fake-detected-buildpack",
   552  				"environment_json": {
   553  					"fake-env-var": "fake-env-var-value"
   554  				},
   555  				"memory": 1024,
   556          "instances": 1,
   557          "disk_quota": 1024,
   558          "state": "started",
   559          "version": "fake-version",
   560          "command": "fake-command",
   561          "console": false,
   562          "debug": null,
   563          "staging_task_id": "fake-staging-task-id",
   564          "package_state": "STAGED",
   565          "health_check_type": "port",
   566          "health_check_timeout": null,
   567          "staging_failed_reason": null,
   568          "staging_failed_description": null,
   569          "diego": true,
   570          "docker_image": null,
   571          "package_updated_at": "2015-11-19T01:00:15Z",
   572          "detected_start_command": "fake-detected-start-command",
   573          "enable_ssh": true,
   574          "docker_credentials_json": {
   575            "redacted_message": "[PRIVATE DATA HIDDEN]"
   576          },
   577          "ports": [
   578            8080,
   579            9090
   580  				],
   581          "space_url": "fake-space-url",
   582          "space": {
   583            "metadata": {
   584              "guid": "fake-space-guid",
   585              "url": "fake-space-url",
   586              "created_at": "2014-05-12T23:36:57Z",
   587              "updated_at": null
   588            },
   589            "entity": {
   590              "name": "fake-space-name",
   591              "organization_guid": "fake-space-organization-guid",
   592              "space_quota_definition_guid": null,
   593              "allow_ssh": true,
   594              "organization_url": "fake-space-organization-url",
   595              "developers_url": "fake-space-developers-url",
   596              "managers_url": "fake-space-managers-url",
   597              "auditors_url": "fake-space-auditors-url",
   598              "apps_url": "fake-space-apps-url",
   599              "routes_url": "fake-space-routes-url",
   600              "domains_url": "fake-space-domains-url",
   601              "service_instances_url": "fake-space-service-instances-url",
   602              "app_events_url": "fake-space-app-events-url",
   603              "events_url": "fake-space-events-url",
   604              "security_groups_url": "fake-space-security-groups-url"
   605            }
   606          },
   607          "stack_url": "fake-stack-url",
   608          "stack": {
   609            "metadata": {
   610              "guid": "fake-stack-guid",
   611              "url": "fake-stack-url",
   612              "created_at": "2015-03-04T18:58:42Z",
   613              "updated_at": null
   614            },
   615            "entity": {
   616              "name": "fake-stack-name",
   617              "description": "fake-stack-description"
   618            }
   619          },
   620          "events_url": "fake-events-url",
   621          "service_bindings_url": "fake-service-bindings-url",
   622          "service_bindings": [],
   623          "routes_url": "fake-routes-url",
   624          "routes": [
   625            {
   626              "metadata": {
   627                "guid": "fake-route-guid",
   628                "url": "fake-route-url",
   629                "created_at": "2014-05-13T21:38:42Z",
   630                "updated_at": null
   631              },
   632              "entity": {
   633                "host": "fake-route-host",
   634                "path": "",
   635                "domain_guid": "fake-route-domain-guid",
   636                "space_guid": "fake-route-space-guid",
   637                "service_instance_guid": null,
   638                "port": 0,
   639                "domain_url": "fake-route-domain-url",
   640                "space_url": "fake-route-space-url",
   641                "apps_url": "fake-route-apps-url"
   642              }
   643            }
   644          ]
   645        }
   646      }
   647    ]
   648  }`
   649  
   650  var getSummaryJSON string = `{
   651  	"guid": "fake-app-guid",
   652  	"name": "fake-app-name",
   653  	"routes": [
   654  	{
   655  		"guid": "fake-route-guid",
   656  		"host": "fake-route-host",
   657  		"domain": {
   658  			"guid": "fake-route-domain-guid",
   659  			"name": "fake-route-domain-name"
   660  		},
   661  		"path": "some-path",
   662      "port": 3333
   663  	}
   664  	],
   665  	"running_instances": 1,
   666  	"services": [
   667  	{
   668  		"guid": "fake-service-guid",
   669  		"name": "fake-service-name",
   670  		"bound_app_count": 1,
   671  		"last_operation": null,
   672  		"dashboard_url": null,
   673  		"service_plan": {
   674  			"guid": "fake-service-plan-guid",
   675  			"name": "fake-service-plan-name",
   676  			"service": {
   677  				"guid": "fake-service-plan-service-guid",
   678  				"label": "fake-service-plan-service-label",
   679  				"provider": null,
   680  				"version": null
   681  			}
   682  		}
   683  	}
   684  	],
   685  	"available_domains": [
   686  	{
   687  		"guid": "fake-available-domain-guid",
   688  		"name": "fake-available-domain-name",
   689  		"owning_organization_guid": "fake-owning-organization-guid"
   690  	}
   691  	],
   692  	"production": false,
   693  	"space_guid": "fake-space-guid",
   694  	"stack_guid": "fake-stack-guid",
   695  	"buildpack": "fake-buildpack",
   696  	"detected_buildpack": "fake-detected-buildpack",
   697  	"environment_json": {
   698  		"fake-env-var": "fake-env-var-value"
   699  	},
   700  	"memory": 1024,
   701  	"instances": 1,
   702  	"disk_quota": 1024,
   703  	"state": "STARTED",
   704  	"version": "fake-version",
   705  	"command": "fake-command",
   706  	"console": false,
   707  	"debug": null,
   708  	"staging_task_id": "fake-staging-task-id",
   709  	"package_state": "STAGED",
   710  	"health_check_type": "port",
   711  	"health_check_timeout": null,
   712  	"staging_failed_reason": null,
   713  	"staging_failed_description": null,
   714  	"diego": true,
   715  	"docker_image": null,
   716  	"package_updated_at": "2015-11-19T01:00:15Z",
   717  	"detected_start_command": "fake-detected-start-command",
   718  	"enable_ssh": true,
   719  	"docker_credentials_json": {
   720  		"redacted_message": "[PRIVATE DATA HIDDEN]"
   721  	},
   722  	"ports": [
   723  		8080,
   724  		9090
   725  	]
   726  }`