github.com/sleungcy-sap/cli@v7.1.0+incompatible/integration/v7/isolated/set_label_command_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  
     7  	"code.cloudfoundry.org/cli/integration/helpers/servicebrokerstub"
     8  
     9  	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
    10  	"code.cloudfoundry.org/cli/integration/helpers"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/gbytes"
    14  	. "github.com/onsi/gomega/gexec"
    15  )
    16  
    17  var _ = Describe("set-label command", func() {
    18  	Describe("help", func() {
    19  		When("--help flag is set", func() {
    20  			It("appears in cf help -a", func() {
    21  				session := helpers.CF("help", "-a")
    22  				Eventually(session).Should(Exit(0))
    23  				Expect(session).To(HaveCommandInCategoryWithDescription("set-label", "METADATA", "Set a label (key-value pairs) for an API resource"))
    24  			})
    25  
    26  			It("Displays command usage to output", func() {
    27  				session := helpers.CF("set-label", "--help")
    28  
    29  				Eventually(session).Should(Say("NAME:"))
    30  				Eventually(session).Should(Say(`\s+set-label - Set a label \(key-value pairs\) for an API resource`))
    31  				Eventually(session).Should(Say("USAGE:"))
    32  				Eventually(session).Should(Say(`\s+cf set-label RESOURCE RESOURCE_NAME KEY=VALUE\.\.\.`))
    33  				Eventually(session).Should(Say("EXAMPLES:"))
    34  				Eventually(session).Should(Say(`\s+cf set-label app dora env=production`))
    35  				Eventually(session).Should(Say(`\s+cf set-label org business pci=true public-facing=false`))
    36  				Eventually(session).Should(Say(`\s+cf set-label buildpack go_buildpack go=1.12 -s cflinuxfs3`))
    37  				Eventually(session).Should(Say("RESOURCES:"))
    38  				Eventually(session).Should(Say(`\s+app`))
    39  				Eventually(session).Should(Say(`\s+buildpack`))
    40  				Eventually(session).Should(Say(`\s+domain`))
    41  				Eventually(session).Should(Say(`\s+org`))
    42  				Eventually(session).Should(Say(`\s+route`))
    43  				Eventually(session).Should(Say(`\s+service-broker`))
    44  				Eventually(session).Should(Say(`\s+service-offering`))
    45  				Eventually(session).Should(Say(`\s+service-plan`))
    46  				Eventually(session).Should(Say(`\s+space`))
    47  				Eventually(session).Should(Say(`\s+stack`))
    48  				Eventually(session).Should(Say("OPTIONS:"))
    49  				Eventually(session).Should(Say(`\s+--stack, -s\s+Specify stack to disambiguate buildpacks with the same name`))
    50  				Eventually(session).Should(Say(`\s+--broker, -b\s+Specify a service broker to disambiguate service offerings or service plans with the same name`))
    51  				Eventually(session).Should(Say(`\s+--offering, -e\s+Specify a service offering to disambiguate service plans with the same name`))
    52  				Eventually(session).Should(Say("SEE ALSO:"))
    53  				Eventually(session).Should(Say(`\s+labels, unset-label`))
    54  
    55  				Eventually(session).Should(Exit(0))
    56  			})
    57  		})
    58  	})
    59  
    60  	When("the environment is set up correctly", func() {
    61  		var (
    62  			orgName       string
    63  			spaceName     string
    64  			username      string
    65  			stackNameBase string
    66  		)
    67  
    68  		testExpectedBehaviors := func(resourceType, resourceTypeFormatted, resourceName string) {
    69  			By("checking the behavior when the resource does not exist", func() {
    70  				unknownResourceName := "non-existent-" + resourceType
    71  				session := helpers.CF("set-label", resourceType, unknownResourceName, "some-key=some-value")
    72  				Eventually(session.Err).Should(Say("%s '%s' not found", resourceTypeFormatted, unknownResourceName))
    73  				Eventually(session).Should(Say("FAILED"))
    74  				Eventually(session).Should(Exit(1))
    75  			})
    76  
    77  			By("checking the behavior when the label has an empty key and an invalid value", func() {
    78  				session := helpers.CF("set-label", resourceType, resourceName, "=test", "sha2=108&eb90d734")
    79  				Eventually(session.Err).Should(Say("Metadata label key error: key cannot be empty string, Metadata label value error: '108&eb90d734' contains invalid characters"))
    80  				Eventually(session).Should(Say("FAILED"))
    81  				Eventually(session).Should(Exit(1))
    82  			})
    83  
    84  			By("checking the behavior when the label does not include a '=' to separate the key and value", func() {
    85  				session := helpers.CF("set-label", resourceType, resourceName, "test-label")
    86  				Eventually(session.Err).Should(Say("Metadata error: no value provided for label 'test-label'"))
    87  				Eventually(session).Should(Say("FAILED"))
    88  				Eventually(session).Should(Exit(1))
    89  			})
    90  		}
    91  
    92  		BeforeEach(func() {
    93  			username, _ = helpers.GetCredentials()
    94  			orgName = helpers.NewOrgName()
    95  			stackNameBase = helpers.NewStackName()
    96  		})
    97  
    98  		When("assigning label to app", func() {
    99  			var appName string
   100  
   101  			BeforeEach(func() {
   102  				spaceName = helpers.NewSpaceName()
   103  				appName = helpers.PrefixedRandomName("app")
   104  
   105  				helpers.SetupCF(orgName, spaceName)
   106  				helpers.WithHelloWorldApp(func(appDir string) {
   107  					Eventually(helpers.CF("push", appName, "-p", appDir, "--no-start")).Should(Exit(0))
   108  				})
   109  			})
   110  
   111  			AfterEach(func() {
   112  				helpers.QuickDeleteOrg(orgName)
   113  			})
   114  
   115  			It("has the expected shared behaviors", func() {
   116  				testExpectedBehaviors("app", "App", appName)
   117  			})
   118  
   119  			It("sets the specified labels on the app", func() {
   120  				session := helpers.CF("set-label", "app", appName, "some-key=some-value", "some-other-key=some-other-value")
   121  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for app %s in org %s / space %s as %s...`), appName, orgName, spaceName, username))
   122  				Eventually(session).Should(Say("OK"))
   123  				Eventually(session).Should(Exit(0))
   124  
   125  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/apps/%s", helpers.AppGUID(appName)), false, helpers.MetadataLabels{
   126  					"some-key":       "some-value",
   127  					"some-other-key": "some-other-value",
   128  				})
   129  			})
   130  
   131  			When("more than one value is provided for the same key", func() {
   132  				It("uses the last value", func() {
   133  					session := helpers.CF("set-label", "app", appName, "owner=sue", "owner=beth")
   134  					Eventually(session).Should(Exit(0))
   135  
   136  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/apps/%s", helpers.AppGUID(appName)), false, helpers.MetadataLabels{
   137  						"owner": "beth",
   138  					})
   139  				})
   140  			})
   141  		})
   142  
   143  		When("assigning label to domain", func() {
   144  			var (
   145  				domainName string
   146  				domain     helpers.Domain
   147  			)
   148  
   149  			BeforeEach(func() {
   150  				domainName = helpers.NewDomainName("labels")
   151  				domain = helpers.NewDomain(orgName, domainName)
   152  
   153  				helpers.SetupCFWithOrgOnly(orgName)
   154  				domain.CreatePrivate()
   155  			})
   156  
   157  			AfterEach(func() {
   158  				domain.DeletePrivate()
   159  				helpers.QuickDeleteOrg(orgName)
   160  			})
   161  
   162  			It("has the expected shared behaviors", func() {
   163  				testExpectedBehaviors("domain", "Domain", domainName)
   164  			})
   165  
   166  			It("sets the specified labels on the domain", func() {
   167  				session := helpers.CF("set-label", "domain", domainName, "some-key=some-value", "some-other-key=some-other-value")
   168  				Eventually(session).Should(Exit(0))
   169  				Expect(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for domain %s as %s...`), domainName, username))
   170  				Expect(session).Should(Say("OK"))
   171  
   172  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/domains?names=%s", domainName), true, helpers.MetadataLabels{
   173  					"some-key":       "some-value",
   174  					"some-other-key": "some-other-value",
   175  				})
   176  			})
   177  
   178  			When("more than one value is provided for the same key", func() {
   179  				It("uses the last value", func() {
   180  					session := helpers.CF("set-label", "domain", domainName, "some-key=some-value", "some-key=some-other-value")
   181  					Eventually(session).Should(Exit(0))
   182  					Expect(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for domain %s as %s...`), domainName, username))
   183  					Expect(session).Should(Say("OK"))
   184  
   185  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/domains?names=%s", domainName), true, helpers.MetadataLabels{
   186  						"some-key": "some-other-value",
   187  					})
   188  				})
   189  			})
   190  		})
   191  
   192  		When("assigning label to space", func() {
   193  			BeforeEach(func() {
   194  				spaceName = helpers.NewSpaceName()
   195  				helpers.SetupCF(orgName, spaceName)
   196  			})
   197  
   198  			AfterEach(func() {
   199  				helpers.QuickDeleteOrg(orgName)
   200  			})
   201  
   202  			It("has the expected shared behaviors", func() {
   203  				testExpectedBehaviors("space", "Space", spaceName)
   204  			})
   205  
   206  			It("sets the specified labels on the space", func() {
   207  				session := helpers.CF("set-label", "space", spaceName, "some-key=some-value", "some-other-key=some-other-value")
   208  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for space %s in org %s as %s...`), spaceName, orgName, username))
   209  				Eventually(session).Should(Say("OK"))
   210  				Eventually(session).Should(Exit(0))
   211  
   212  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/spaces/%s", helpers.GetSpaceGUID(spaceName)), false, helpers.MetadataLabels{
   213  					"some-key":       "some-value",
   214  					"some-other-key": "some-other-value",
   215  				})
   216  			})
   217  
   218  			When("more than one value is provided for the same key", func() {
   219  				It("uses the last value", func() {
   220  					session := helpers.CF("set-label", "space", spaceName, "owner=sue", "owner=beth")
   221  					Eventually(session).Should(Exit(0))
   222  
   223  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/spaces/%s", helpers.GetSpaceGUID(spaceName)), false, helpers.MetadataLabels{
   224  						"owner": "beth",
   225  					})
   226  				})
   227  			})
   228  		})
   229  
   230  		When("assigning label to org", func() {
   231  			BeforeEach(func() {
   232  				helpers.SetupCFWithOrgOnly(orgName)
   233  			})
   234  
   235  			AfterEach(func() {
   236  				helpers.QuickDeleteOrg(orgName)
   237  			})
   238  
   239  			It("has the expected shared behaviors", func() {
   240  				testExpectedBehaviors("org", "Organization", orgName)
   241  			})
   242  
   243  			It("sets the specified labels on the org", func() {
   244  				session := helpers.CF("set-label", "org", orgName, "pci=true", "public-facing=false")
   245  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for org %s as %s...`), orgName, username))
   246  				Eventually(session).Should(Say("OK"))
   247  				Eventually(session).Should(Exit(0))
   248  
   249  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/organizations/%s", helpers.GetOrgGUID(orgName)), false, helpers.MetadataLabels{
   250  					"pci":           "true",
   251  					"public-facing": "false",
   252  				})
   253  			})
   254  
   255  			When("more than one value is provided for the same key", func() {
   256  				It("uses the last value", func() {
   257  					session := helpers.CF("set-label", "org", orgName, "owner=sue", "owner=beth")
   258  					Eventually(session).Should(Exit(0))
   259  
   260  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/organizations/%s", helpers.GetOrgGUID(orgName)), false, helpers.MetadataLabels{
   261  						"owner": "beth",
   262  					})
   263  				})
   264  			})
   265  		})
   266  
   267  		When("assigning label to route", func() {
   268  			var (
   269  				orgGUID    string
   270  				routeName  string
   271  				domainName string
   272  				domain     helpers.Domain
   273  			)
   274  			BeforeEach(func() {
   275  				orgName = helpers.NewOrgName()
   276  				spaceName = helpers.NewSpaceName()
   277  				helpers.SetupCF(orgName, spaceName)
   278  
   279  				orgGUID = helpers.GetOrgGUID(orgName)
   280  				domainName = helpers.NewDomainName()
   281  				domain = helpers.NewDomain(orgName, domainName)
   282  				domain.Create()
   283  				Eventually(helpers.CF("create-route", domainName)).Should(Exit(0))
   284  				routeName = domainName
   285  			})
   286  
   287  			AfterEach(func() {
   288  				Eventually(helpers.CF("delete-route", domainName, "-f")).Should(Exit(0))
   289  				domain.Delete()
   290  				helpers.QuickDeleteOrg(orgName)
   291  			})
   292  
   293  			It("has the expected shared behaviors", func() {
   294  				// The Domain is checked first, hence why the error message says 'Domain' and not 'Route'
   295  				testExpectedBehaviors("route", "Domain", routeName)
   296  			})
   297  
   298  			When("the route contains a port", func() {
   299  				var tcpDomain helpers.Domain
   300  
   301  				BeforeEach(func() {
   302  					tcpDomainName := helpers.NewDomainName()
   303  					tcpDomain = helpers.NewDomain(orgName, tcpDomainName)
   304  					tcpDomain.CreateWithRouterGroup(helpers.FindOrCreateTCPRouterGroup(0))
   305  
   306  					Eventually(helpers.CF("create-route", tcpDomainName, "--port", "1028")).Should(Exit(0))
   307  					Eventually(helpers.CF("create-route", tcpDomainName, "--port", "1029")).Should(Exit(0))
   308  					routeName = tcpDomainName + ":1028"
   309  				})
   310  
   311  				AfterEach(func() {
   312  					tcpDomain.DeleteShared()
   313  				})
   314  
   315  				It("sets the specified labels on the route", func() {
   316  					session := helpers.CF("set-label", "route", routeName, "some-key=some-value", "some-other-key=some-other-value")
   317  
   318  					Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for route %s in org %s / space %s as %s...`), routeName, orgName, spaceName, username))
   319  					Eventually(session).Should(Say("OK"))
   320  					Eventually(session).Should(Exit(0))
   321  
   322  					helpers.CheckExpectedLabels("/v3/routes?ports=1028", true, helpers.MetadataLabels{
   323  						"some-key":       "some-value",
   324  						"some-other-key": "some-other-value",
   325  					})
   326  
   327  					helpers.CheckExpectedLabels("/v3/routes?ports=1029", true, helpers.MetadataLabels{})
   328  				})
   329  			})
   330  
   331  			When("the route is unknown", func() {
   332  				It("displays an error", func() {
   333  					invalidRoute := "non-existent-host." + domainName
   334  					session := helpers.CF("set-label", "route", invalidRoute, "some-key=some-value")
   335  					Eventually(session.Err).Should(Say(fmt.Sprintf("Route with host 'non-existent-host' and domain '%s' not found", domainName)))
   336  					Eventually(session).Should(Say("FAILED"))
   337  					Eventually(session).Should(Exit(1))
   338  				})
   339  			})
   340  
   341  			It("sets the specified labels on the route", func() {
   342  				session := helpers.CF("set-label", "route", routeName, "some-key=some-value", "some-other-key=some-other-value")
   343  
   344  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for route %s in org %s / space %s as %s...`), routeName, orgName, spaceName, username))
   345  				Eventually(session).Should(Say("OK"))
   346  				Eventually(session).Should(Exit(0))
   347  
   348  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/routes?organization_guids=%s", orgGUID), true, helpers.MetadataLabels{
   349  					"some-key":       "some-value",
   350  					"some-other-key": "some-other-value",
   351  				})
   352  			})
   353  
   354  			When("more than one value is provided for the same key", func() {
   355  				It("uses the last value", func() {
   356  					session := helpers.CF("set-label", "route", routeName, "owner=sue", "owner=beth")
   357  					Eventually(session).Should(Exit(0))
   358  
   359  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/routes?organization_guids=%s", orgGUID), true, helpers.MetadataLabels{
   360  						"owner": "beth",
   361  					})
   362  				})
   363  			})
   364  		})
   365  
   366  		When("assigning label to buildpack", func() {
   367  			var (
   368  				buildpackName string
   369  			)
   370  
   371  			BeforeEach(func() {
   372  				helpers.LoginCF()
   373  				buildpackName = helpers.NewBuildpackName()
   374  			})
   375  
   376  			When("the buildpack exists for at most one stack", func() {
   377  				var (
   378  					currentStack string
   379  				)
   380  
   381  				BeforeEach(func() {
   382  					currentStack = helpers.PreferredStack()
   383  					helpers.BuildpackWithStack(func(buildpackPath string) {
   384  						session := helpers.CF("create-buildpack", buildpackName, buildpackPath, "98")
   385  						Eventually(session).Should(Exit(0))
   386  					}, currentStack)
   387  				})
   388  
   389  				AfterEach(func() {
   390  					helpers.CF("delete-buildpack", buildpackName, "-f", "-s", currentStack)
   391  				})
   392  
   393  				It("has the expected shared behaviors", func() {
   394  					testExpectedBehaviors("buildpack", "Buildpack", buildpackName)
   395  				})
   396  
   397  				It("sets the specified labels on the buildpack", func() {
   398  					session := helpers.CF("set-label", "buildpack", buildpackName, "pci=true", "public-facing=false")
   399  					Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for buildpack %s as %s...`), buildpackName, username))
   400  					Eventually(session).Should(Say("OK"))
   401  					Eventually(session).Should(Exit(0))
   402  
   403  					buildpackGUID := helpers.BuildpackGUIDByNameAndStack(buildpackName, currentStack)
   404  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/buildpacks/%s", buildpackGUID), false, helpers.MetadataLabels{
   405  						"pci":           "true",
   406  						"public-facing": "false",
   407  					})
   408  				})
   409  
   410  				When("the buildpack exists for multiple stacks", func() {
   411  					var stacks []string
   412  
   413  					BeforeEach(func() {
   414  						stacks = []string{helpers.PreferredStack(), helpers.CreateStack()}
   415  
   416  						helpers.BuildpackWithStack(func(buildpackPath string) {
   417  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackPath, "99")
   418  							Eventually(createSession).Should(Exit(0))
   419  						}, stacks[1])
   420  					})
   421  					AfterEach(func() {
   422  						helpers.CF("delete-buildpack", buildpackName, "-f", "-s", stacks[1])
   423  						helpers.DeleteStack(stacks[1])
   424  					})
   425  
   426  					When("stack is not specified", func() {
   427  						It("displays an error", func() {
   428  							session := helpers.CF("set-label", "buildpack", buildpackName, "some-key=some-value")
   429  							Eventually(session.Err).Should(Say(fmt.Sprintf("Multiple buildpacks named %s found. Specify a stack name by using a '-s' flag.", buildpackName)))
   430  							Eventually(session).Should(Say("FAILED"))
   431  							Eventually(session).Should(Exit(1))
   432  						})
   433  					})
   434  
   435  					When("stack is specified", func() {
   436  						It("sets the specified labels on the correct buildpack", func() {
   437  							session := helpers.CF("set-label", "buildpack", buildpackName, "pci=true", "public-facing=false", "--stack", stacks[1])
   438  							Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for buildpack %s with stack %s as %s...`), buildpackName, stacks[1], username))
   439  							Eventually(session).Should(Say("OK"))
   440  							Eventually(session).Should(Exit(0))
   441  
   442  							buildpackGUID := helpers.BuildpackGUIDByNameAndStack(buildpackName, stacks[1])
   443  							helpers.CheckExpectedLabels(fmt.Sprintf("/v3/buildpacks/%s", buildpackGUID), false, helpers.MetadataLabels{
   444  								"pci":           "true",
   445  								"public-facing": "false",
   446  							})
   447  						})
   448  					})
   449  				})
   450  
   451  				When("the buildpack exists in general but does NOT exist for the specified stack", func() {
   452  					It("displays an error", func() {
   453  						session := helpers.CF("set-label", "buildpack", buildpackName, "some-key=some-value", "--stack", "FAKE")
   454  						Eventually(session.Err).Should(Say(fmt.Sprintf("Buildpack '%s' with stack 'FAKE' not found", buildpackName)))
   455  						Eventually(session).Should(Say("FAILED"))
   456  						Eventually(session).Should(Exit(1))
   457  					})
   458  				})
   459  
   460  				When("more than one value is provided for the same key", func() {
   461  					It("uses the last value", func() {
   462  						session := helpers.CF("set-label", "buildpack", buildpackName, "owner=sue", "owner=beth")
   463  						Eventually(session).Should(Exit(0))
   464  
   465  						buildpackGUID := helpers.BuildpackGUIDByNameAndStack(buildpackName, currentStack)
   466  						helpers.CheckExpectedLabels(fmt.Sprintf("/v3/buildpacks/%s", buildpackGUID), false, helpers.MetadataLabels{
   467  							"owner": "beth",
   468  						})
   469  					})
   470  				})
   471  			})
   472  
   473  			When("the buildpack exists for multiple stacks", func() {
   474  				var (
   475  					stacks             [3]string
   476  					buildpackGUIDs     [3]string
   477  					testWithStackCount int
   478  				)
   479  
   480  				BeforeEach(func() {
   481  					stacks[0] = helpers.PreferredStack()
   482  					testWithStackCount += 1
   483  					stacks[1] = helpers.CreateStack(fmt.Sprintf("%s-%d", stackNameBase, testWithStackCount))
   484  
   485  					for i := 0; i < 2; i++ {
   486  						helpers.BuildpackWithStack(func(buildpackPath string) {
   487  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackPath,
   488  								fmt.Sprintf("%d", 95+i))
   489  							Eventually(createSession).Should(Exit(0))
   490  							buildpackGUIDs[i] = helpers.BuildpackGUIDByNameAndStack(buildpackName, stacks[i])
   491  						}, stacks[i])
   492  					}
   493  					helpers.CF("curl", "/v3/buildpacks?names="+buildpackName)
   494  				})
   495  
   496  				AfterEach(func() {
   497  					helpers.CF("delete-buildpack", buildpackName, "-f", "-s", stacks[0])
   498  					helpers.CF("delete-buildpack", buildpackName, "-f", "-s", stacks[1])
   499  					helpers.DeleteStack(stacks[1])
   500  				})
   501  
   502  				When("all buildpacks are stack-scoped", func() {
   503  					When("no stack is specified", func() {
   504  						It("displays an error", func() {
   505  							session := helpers.CF("set-label", "buildpack", buildpackName, "some-key=some-value")
   506  							Eventually(session.Err).Should(Say(fmt.Sprintf("Multiple buildpacks named %s found. Specify a stack name by using a '-s' flag.", buildpackName)))
   507  							Eventually(session).Should(Say("FAILED"))
   508  							Eventually(session).Should(Exit(1))
   509  						})
   510  					})
   511  
   512  					When("a non-existent stack is specified", func() {
   513  						It("displays an error", func() {
   514  							bogusStackName := stacks[0] + "-bogus-" + stacks[1]
   515  							session := helpers.CF("set-label", "buildpack", buildpackName, "olive=3", "mangosteen=4", "--stack", bogusStackName)
   516  							Eventually(session.Err).Should(Say(regexp.QuoteMeta(fmt.Sprintf("Buildpack '%s' with stack '%s' not found", buildpackName, bogusStackName))))
   517  							Eventually(session).Should(Say("FAILED"))
   518  							Eventually(session).Should(Exit(1))
   519  						})
   520  					})
   521  
   522  					When("an existing stack is specified", func() {
   523  						It("updates the correct buildpack", func() {
   524  							session := helpers.CF("set-label", "buildpack", buildpackName, "peach=5", "quince=6", "--stack", stacks[0])
   525  							Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for buildpack %s with stack %s as %s...`), buildpackName, stacks[0], username))
   526  							Eventually(session).Should(Say("OK"))
   527  							Eventually(session).Should(Exit(0))
   528  
   529  							helpers.CheckExpectedLabels(fmt.Sprintf("/v3/buildpacks/%s", buildpackGUIDs[0]), false, helpers.MetadataLabels{
   530  								"peach":  "5",
   531  								"quince": "6",
   532  							})
   533  						})
   534  					})
   535  				})
   536  
   537  				When("one of the buildpacks is not stack-scoped", func() {
   538  					BeforeEach(func() {
   539  						helpers.BuildpackWithoutStack(func(buildpackPath string) {
   540  							createSession := helpers.CF("create-buildpack", buildpackName, buildpackPath, "97")
   541  							Eventually(createSession).Should(Exit(0))
   542  							buildpackGUIDs[2] = helpers.BuildpackGUIDByNameAndStack(buildpackName, "")
   543  						})
   544  					})
   545  					AfterEach(func() {
   546  						helpers.CF("delete-buildpack", buildpackName, "-f")
   547  					})
   548  
   549  					When("no stack is specified", func() {
   550  						It("updates the unscoped buildpack", func() {
   551  							session := helpers.CF("set-label", "buildpack", buildpackName, "mango=1", "figs=2")
   552  							Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for buildpack %s as %s...`), buildpackName, username))
   553  							Eventually(session).Should(Say("OK"))
   554  							Eventually(session).Should(Exit(0))
   555  
   556  							helpers.CheckExpectedLabels(fmt.Sprintf("/v3/buildpacks/%s", buildpackGUIDs[2]), false, helpers.MetadataLabels{
   557  								"mango": "1",
   558  								"figs":  "2",
   559  							})
   560  						})
   561  					})
   562  
   563  					When("an existing stack is specified", func() {
   564  						It("updates the correct buildpack", func() {
   565  							session := helpers.CF("set-label", "buildpack", buildpackName, "tangelo=3", "lemon=4", "--stack", stacks[1])
   566  							Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for buildpack %s with stack %s as %s...`), buildpackName, stacks[1], username))
   567  							Eventually(session).Should(Say("OK"))
   568  							Eventually(session).Should(Exit(0))
   569  
   570  							helpers.CheckExpectedLabels(fmt.Sprintf("/v3/buildpacks/%s", buildpackGUIDs[1]), false, helpers.MetadataLabels{
   571  								"tangelo": "3",
   572  								"lemon":   "4",
   573  							})
   574  						})
   575  					})
   576  
   577  					When("a non-existent stack is specified", func() {
   578  						It("displays an error", func() {
   579  							bogusStackName := stacks[0] + "-bogus-" + stacks[1]
   580  							session := helpers.CF("set-label", "buildpack", buildpackName, "olive=3", "mangosteen=4", "--stack", bogusStackName)
   581  							Eventually(session.Err).Should(Say(regexp.QuoteMeta(fmt.Sprintf("Buildpack '%s' with stack '%s' not found", buildpackName, bogusStackName))))
   582  							Eventually(session).Should(Say("FAILED"))
   583  							Eventually(session).Should(Exit(1))
   584  						})
   585  					})
   586  				})
   587  			})
   588  		})
   589  
   590  		When("assigning label to stack", func() {
   591  			var (
   592  				stackName string
   593  				stackGUID string
   594  			)
   595  
   596  			BeforeEach(func() {
   597  				helpers.LoginCF()
   598  				stackName, stackGUID = helpers.CreateStackWithGUID()
   599  			})
   600  
   601  			AfterEach(func() {
   602  				deleteResourceByGUID(stackGUID, "stacks")
   603  			})
   604  
   605  			It("has the expected shared behaviors", func() {
   606  				testExpectedBehaviors("stack", "Stack", stackName)
   607  			})
   608  
   609  			It("sets the specified labels on the stack", func() {
   610  				session := helpers.CF("set-label", "stack", stackName, "pci=true", "public-facing=false")
   611  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for stack %s as %s...`), stackName, username))
   612  				Eventually(session).Should(Say("OK"))
   613  				Eventually(session).Should(Exit(0))
   614  
   615  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/stacks/%s", stackGUID), false, helpers.MetadataLabels{
   616  					"pci":           "true",
   617  					"public-facing": "false",
   618  				})
   619  			})
   620  
   621  			When("more than one value is provided for the same key", func() {
   622  				It("uses the last value", func() {
   623  					session := helpers.CF("set-label", "stack", stackName, "owner=sue", "owner=beth")
   624  					Eventually(session).Should(Exit(0))
   625  
   626  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/stacks/%s", stackGUID), false, helpers.MetadataLabels{
   627  						"owner": "beth",
   628  					})
   629  				})
   630  			})
   631  		})
   632  
   633  		When("assigning label to service-broker", func() {
   634  			var broker *servicebrokerstub.ServiceBrokerStub
   635  
   636  			BeforeEach(func() {
   637  				orgName = helpers.NewOrgName()
   638  				spaceName = helpers.NewSpaceName()
   639  				helpers.SetupCF(orgName, spaceName)
   640  				broker = servicebrokerstub.Register()
   641  			})
   642  
   643  			AfterEach(func() {
   644  				helpers.QuickDeleteOrg(orgName)
   645  				broker.Forget()
   646  			})
   647  
   648  			It("has the expected shared behaviors", func() {
   649  				testExpectedBehaviors("service-broker", "Service broker", broker.Name)
   650  			})
   651  
   652  			It("sets the specified labels on the service-broker", func() {
   653  				session := helpers.CF("set-label", "service-broker", broker.Name, "some-key=some-value", "some-other-key=some-other-value")
   654  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for service-broker %s as %s...`), broker.Name, username))
   655  				Eventually(session).Should(Say("OK"))
   656  				Eventually(session).Should(Exit(0))
   657  
   658  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/service_brokers?names=%s", broker.Name), true, helpers.MetadataLabels{
   659  					"some-key":       "some-value",
   660  					"some-other-key": "some-other-value",
   661  				})
   662  			})
   663  
   664  			When("more than one value is provided for the same key", func() {
   665  				It("uses the last value", func() {
   666  					session := helpers.CF("set-label", "service-broker", broker.Name, "owner=sue", "owner=beth")
   667  					Eventually(session).Should(Exit(0))
   668  
   669  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/service_brokers?names=%s", broker.Name), true, helpers.MetadataLabels{
   670  						"owner": "beth",
   671  					})
   672  				})
   673  			})
   674  		})
   675  
   676  		When("assigning label to service-offering", func() {
   677  			var (
   678  				broker              *servicebrokerstub.ServiceBrokerStub
   679  				serviceOfferingName string
   680  			)
   681  
   682  			BeforeEach(func() {
   683  				orgName = helpers.NewOrgName()
   684  				spaceName = helpers.NewSpaceName()
   685  				helpers.SetupCF(orgName, spaceName)
   686  				broker = servicebrokerstub.Register()
   687  				serviceOfferingName = broker.Services[0].Name
   688  			})
   689  
   690  			AfterEach(func() {
   691  				helpers.QuickDeleteOrg(orgName)
   692  				broker.Forget()
   693  			})
   694  
   695  			It("has the expected shared behaviors", func() {
   696  				testExpectedBehaviors("service-offering", "Service offering", serviceOfferingName)
   697  			})
   698  
   699  			It("sets the specified labels", func() {
   700  				session := helpers.CF("set-label", "service-offering", serviceOfferingName, "some-key=some-value", "some-other-key=some-other-value")
   701  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for service-offering %s as %s...`), serviceOfferingName, username))
   702  				Eventually(session).Should(Say("OK"))
   703  				Eventually(session).Should(Exit(0))
   704  
   705  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/service_offerings?names=%s", serviceOfferingName), true, helpers.MetadataLabels{
   706  					"some-key":       "some-value",
   707  					"some-other-key": "some-other-value",
   708  				})
   709  			})
   710  
   711  			When("more than one value is provided for the same key", func() {
   712  				It("uses the last value", func() {
   713  					session := helpers.CF("set-label", "service-broker", broker.Name, "owner=sue", "owner=beth")
   714  					Eventually(session).Should(Exit(0))
   715  
   716  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/service_brokers?names=%s", broker.Name), true, helpers.MetadataLabels{
   717  						"owner": "beth",
   718  					})
   719  				})
   720  			})
   721  
   722  			When("the service broker name is specified as part of the command", func() {
   723  				It("sets the specified labels", func() {
   724  					session := helpers.CF("set-label", "-b", broker.Name, "service-offering", serviceOfferingName, "some-key=some-value", "some-other-key=some-other-value")
   725  					Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for service-offering %s from service broker %s as %s...`), serviceOfferingName, broker.Name, username))
   726  					Eventually(session).Should(Say("OK"))
   727  					Eventually(session).Should(Exit(0))
   728  
   729  					helpers.CheckExpectedLabels(fmt.Sprintf("/v3/service_offerings?names=%s", serviceOfferingName), true, helpers.MetadataLabels{
   730  						"some-key":       "some-value",
   731  						"some-other-key": "some-other-value",
   732  					})
   733  				})
   734  			})
   735  		})
   736  
   737  		When("assigning label to service-plan", func() {
   738  			var (
   739  				broker              *servicebrokerstub.ServiceBrokerStub
   740  				servicePlanName     string
   741  				serviceOfferingName string
   742  			)
   743  
   744  			BeforeEach(func() {
   745  				orgName = helpers.NewOrgName()
   746  				spaceName = helpers.NewSpaceName()
   747  				helpers.SetupCF(orgName, spaceName)
   748  				broker = servicebrokerstub.Register()
   749  				servicePlanName = broker.Services[0].Plans[0].Name
   750  				serviceOfferingName = broker.Services[0].Name
   751  			})
   752  
   753  			AfterEach(func() {
   754  				helpers.QuickDeleteOrg(orgName)
   755  				broker.Forget()
   756  			})
   757  
   758  			It("has the expected shared behaviors", func() {
   759  				testExpectedBehaviors("service-plan", "Service plan", servicePlanName)
   760  			})
   761  
   762  			It("sets the specified labels", func() {
   763  				session := helpers.CF("set-label", "service-plan", servicePlanName, "-b", broker.Name, "-e", serviceOfferingName, "some-key=some-value", "some-other-key=some-other-value")
   764  				Eventually(session).Should(Say(regexp.QuoteMeta(`Setting label(s) for service-plan %s from service offering %s / service broker %s as %s...`), servicePlanName, serviceOfferingName, broker.Name, username))
   765  				Eventually(session).Should(Say("OK"))
   766  				Eventually(session).Should(Exit(0))
   767  
   768  				helpers.CheckExpectedLabels(fmt.Sprintf("/v3/service_plans?names=%s", servicePlanName), true, helpers.MetadataLabels{
   769  					"some-key":       "some-value",
   770  					"some-other-key": "some-other-value",
   771  				})
   772  			})
   773  		})
   774  
   775  	})
   776  })
   777  
   778  func deleteResourceByGUID(guid string, urlType string) {
   779  	session := helpers.CF("curl", "-v", "-X", "DELETE",
   780  		fmt.Sprintf("/v3/%s/%s", urlType, guid))
   781  	Eventually(session).Should(Exit(0))
   782  	Eventually(session).Should(Say(`(?:204 No Content|202 Accepted)`))
   783  }