func (b ServiceBroker) Destroy() {
	cf.AsUser(b.context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		Expect(cf.Cf("purge-service-offering", b.Service.Name, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})
	b.Delete()
	Expect(cf.Cf("delete", b.Name, "-f", "-r").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
}
func (context *ConfiguredContext) Setup() {
	cf.AsUser(context.AdminUserContext(), func() {
		definition := quotaDefinition{
			Name: context.quotaDefinitionName,

			TotalServices: "100",
			TotalRoutes:   "1000",
			MemoryLimit:   "10G",

			NonBasicServicesAllowed: true,
		}

		args := []string{
			"create-quota",
			context.quotaDefinitionName,
			"-m", definition.MemoryLimit,
			"-r", definition.TotalRoutes,
			"-s", definition.TotalServices,
		}
		if definition.NonBasicServicesAllowed {
			args = append(args, "--allow-paid-service-plans")
		}

		Expect(cf.Cf(args...).Wait(CF_API_TIMEOUT)).To(Exit(0))

		createUserSession := cf.Cf("create-user", context.regularUserUsername, context.regularUserPassword)
		createUserSession.Wait(CF_API_TIMEOUT)
		if createUserSession.ExitCode() != 0 {
			Expect(createUserSession.Out).To(Say("scim_resource_already_exists"))
		}

		Expect(cf.Cf("create-org", context.organizationName).Wait(CF_API_TIMEOUT)).To(Exit(0))
		Expect(cf.Cf("set-quota", context.organizationName, definition.Name).Wait(CF_API_TIMEOUT)).To(Exit(0))
	})
}
Exemple #3
0
func (context *ConfiguredContext) Setup() {
	cf.AsUser(context.AdminUserContext(), func() {
		channel := cf.Cf("create-user", context.regularUserUsername, context.regularUserPassword)
		select {
		case <-channel.Out.Detect("OK"):
		case <-channel.Out.Detect("scim_resource_already_exists"):
		case <-time.After(ScaledTimeout(10 * time.Second)):
			Fail("failed to create user")
		}

		definition := quotaDefinition{
			Name: context.quotaDefinitionName,

			TotalServices: 100,
			TotalRoutes:   1000,

			MemoryLimit: 10240,

			NonBasicServicesAllowed: true,
		}

		definitionPayload, err := json.Marshal(definition)
		Expect(err).ToNot(HaveOccurred())

		var response cf.GenericResource

		cf.ApiRequest("POST", "/v2/quota_definitions", &response, string(definitionPayload))

		context.quotaDefinitionGUID = response.Metadata.Guid

		Eventually(cf.Cf("create-org", context.organizationName), ScaledTimeout(60*time.Second)).Should(Exit(0))
		Eventually(cf.Cf("set-quota", context.organizationName, definition.Name), ScaledTimeout(60*time.Second)).Should(Exit(0))
	})
}
Exemple #4
0
func (c *context) Teardown() {

	userOrg := c.RegularUserContext().Org

	cf.RestoreUserContext(c.RegularUserContext(), c.shortTimeout, c.originalCfHomeDir, c.currentCfHomeDir)

	cf.AsUser(c.AdminUserContext(), c.shortTimeout, func() {
		runner.NewCmdRunner(cf.Cf("delete-user", "-f", c.regularUserUsername), c.longTimeout).Run()

		// delete-space does not provide an org flag, so we must target the Org first
		runner.NewCmdRunner(cf.Cf("target", "-o", userOrg), c.longTimeout).Run()
		runner.NewCmdRunner(cf.Cf("delete-space", "-f", c.spaceName), c.longTimeout).Run()

		if !c.useExistingOrg {
			runner.NewCmdRunner(cf.Cf("delete-org", "-f", c.organizationName), c.longTimeout).Run()

			cf.ApiRequest(
				"DELETE",
				"/v2/quota_definitions/"+c.quotaDefinitionGUID+"?recursive=true",
				nil,
				c.ShortTimeout(),
			)
		}

		if c.config.CreatePermissiveSecurityGroup {
			runner.NewCmdRunner(cf.Cf("delete-security-group", "-f", c.securityGroupName), c.shortTimeout).Run()
		}
	})
}
func (b ServiceBroker) PublicizePlan(url string) {
	jsonMap := make(map[string]bool)
	jsonMap["public"] = true
	planJson, _ := json.Marshal(jsonMap)
	cf.AsUser(b.context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		Expect(cf.Cf("curl", url, "-X", "PUT", "-d", string(planJson)).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})
}
func deleteServiceBroker(brokerName string) {
	config = helpers.LoadConfig()
	context := helpers.NewContext(config)
	cf.AsUser(context.AdminUserContext(), context.ShortTimeout(), func() {
		responseBuffer := cf.Cf("delete-service-broker", brokerName, "-f")
		Expect(responseBuffer.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})
}
func (b ServiceBroker) Delete() {
	cf.AsUser(b.context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		Expect(cf.Cf("delete-service-broker", b.Name, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))

		brokers := cf.Cf("service-brokers").Wait(DEFAULT_TIMEOUT)
		Expect(brokers).To(Exit(0))
		Expect(brokers.Out.Contents()).ToNot(ContainSubstring(b.Name))
	})
}
func lastPageUsageEvents(appName string) []AppUsageEvent {
	var response AppUsageEvents

	cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		cf.ApiRequest("GET", "/v2/app_usage_events?order-direction=desc&page=1", &response, DEFAULT_TIMEOUT)
	})

	return response.Resources
}
func (e *Environment) Setup() {
	e.context.Setup()

	cf.AsUser(e.context.AdminUserContext(), func() {
		setUpSpaceWithUserAccess(e.context.RegularUserContext())
	})

	e.originalCfHomeDir, e.currentCfHomeDir = cf.InitiateUserContext(e.context.RegularUserContext())
	cf.TargetSpace(e.context.RegularUserContext())
}
func (context *ConfiguredContext) Teardown() {
	cf.AsUser(context.AdminUserContext(), func() {
		Expect(cf.Cf("delete-user", "-f", context.regularUserUsername).Wait(CF_API_TIMEOUT)).To(Exit(0))

		if !context.isPersistent {
			Expect(cf.Cf("delete-org", "-f", context.organizationName).Wait(CF_API_TIMEOUT)).To(Exit(0))

			Expect(cf.Cf("delete-quota", "-f", context.quotaDefinitionName).Wait(CF_API_TIMEOUT)).To(Exit(0))
		}
	})
}
Exemple #11
0
func (context *ConfiguredContext) Teardown() {
	cf.AsUser(context.AdminUserContext(), context.shortTimeout, func() {

		if !context.config.ShouldKeepUser {
			runner.NewCmdRunner(cf.Cf("delete-user", "-f", context.regularUserUsername), context.shortTimeout).Run()
		}

		if !context.isPersistent {
			runner.NewCmdRunner(cf.Cf("delete-org", "-f", context.organizationName), context.shortTimeout).Run()
			runner.NewCmdRunner(cf.Cf("delete-quota", "-f", context.quotaDefinitionName), context.shortTimeout).Run()
		}
	})
}
func lastAppUsageEvent(appName string, state string) (bool, AppUsageEvent) {
	var response AppUsageEvents
	cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		cf.ApiRequest("GET", "/v2/app_usage_events?order-direction=desc&page=1&results-per-page=150", &response, DEFAULT_TIMEOUT)
	})

	for _, event := range response.Resources {
		if event.Entity.AppName == appName && event.Entity.State == state {
			return true, event
		}
	}

	return false, AppUsageEvent{}
}
Exemple #13
0
func (context *ConfiguredContext) Teardown() {
	cf.AsUser(context.AdminUserContext(), func() {
		Eventually(cf.Cf("delete-user", "-f", context.regularUserUsername), ScaledTimeout(60*time.Second)).Should(Exit(0))

		if !context.isPersistent {
			Eventually(cf.Cf("delete-org", "-f", context.organizationName), ScaledTimeout(60*time.Second)).Should(Exit(0))

			cf.ApiRequest(
				"DELETE",
				"/v2/quota_definitions/"+context.quotaDefinitionGUID+"?recursive=true",
				nil,
			)
		}
	})
}
func (b ServiceBroker) PublicizePlans() {
	url := fmt.Sprintf("/v2/services?inline-relations-depth=1&q=label:%s", b.Service.Name)
	var session *Session
	cf.AsUser(b.context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		session = cf.Cf("curl", url).Wait(DEFAULT_TIMEOUT)
		Expect(session).To(Exit(0))
	})
	structure := ServicesResponse{}
	json.Unmarshal(session.Out.Contents(), &structure)

	for _, service := range structure.Resources {
		if service.Entity.Label == b.Service.Name {
			for _, plan := range service.Entity.ServicePlans {
				if b.HasPlan(plan.Entity.Name) {
					b.PublicizePlan(plan.Metadata.Url)
				}
			}
		}
	}
}
func getCfHomeConfig() *cfHomeConfig {
	myCfHomeConfig := &cfHomeConfig{}

	cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		path := filepath.Join(os.Getenv("CF_HOME"), ".cf", "config.json")

		configFile, err := os.Open(path)
		if err != nil {
			panic(err)
		}

		decoder := json.NewDecoder(configFile)
		err = decoder.Decode(myCfHomeConfig)
		if err != nil {
			panic(err)
		}
	})

	return myCfHomeConfig
}
Exemple #16
0
func (c *context) Setup() {
	cf.AsUser(c.AdminUserContext(), c.shortTimeout, func() {
		runner.NewCmdRunner(cf.Cf("create-user", c.regularUserUsername, c.regularUserPassword), c.shortTimeout).Run()

		if c.useExistingOrg == false {

			definition := QuotaDefinition{
				Name: c.quotaDefinitionName,

				TotalServices: 100,
				TotalRoutes:   1000,

				MemoryLimit: 10240,

				NonBasicServicesAllowed: true,
			}

			definitionPayload, err := json.Marshal(definition)
			gomega.Expect(err).ToNot(gomega.HaveOccurred())

			var response cf.GenericResource
			cf.ApiRequest("POST", "/v2/quota_definitions", &response, c.shortTimeout, string(definitionPayload))

			c.quotaDefinitionGUID = response.Metadata.Guid

			runner.NewCmdRunner(cf.Cf("create-org", c.organizationName), c.shortTimeout).Run()
			runner.NewCmdRunner(cf.Cf("set-quota", c.organizationName, c.quotaDefinitionName), c.shortTimeout).Run()
		}

		c.setUpSpaceWithUserAccess(c.RegularUserContext())

		if c.config.CreatePermissiveSecurityGroup {
			c.createPermissiveSecurityGroup()
		}
	})

	c.originalCfHomeDir, c.currentCfHomeDir = cf.InitiateUserContext(c.RegularUserContext(), c.shortTimeout)
	cf.TargetSpace(c.RegularUserContext(), c.shortTimeout)
}
func createServiceBroker() (string, string, string) {
	serviceBrokerAsset := assets.NewAssets().ServiceBroker
	serviceBrokerAppName := PushApp(serviceBrokerAsset, config.RubyBuildpackName)

	serviceName := initiateBrokerConfig(serviceBrokerAppName)

	brokerName := generator.PrefixedRandomName("RATS-BROKER-")
	brokerUrl := helpers.AppUri(serviceBrokerAppName, "")

	config = helpers.LoadConfig()
	context := helpers.NewContext(config)
	cf.AsUser(context.AdminUserContext(), context.ShortTimeout(), func() {
		session := cf.Cf("create-service-broker", brokerName, "user", "password", brokerUrl)
		Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))

		session = cf.Cf("enable-service-access", serviceName)
		Expect(session.Wait(DEFAULT_TIMEOUT)).To(Exit(0))

	})

	return brokerName, serviceBrokerAppName, serviceName
}
func (c *context) Teardown() {
	cf.RestoreUserContext(c.RegularUserContext(), c.shortTimeout, c.originalCfHomeDir, c.currentCfHomeDir)

	cf.AsUser(c.AdminUserContext(), c.shortTimeout, func() {
		runner.NewCmdRunner(cf.Cf("delete-user", "-f", c.regularUserUsername), c.longTimeout).Run()

		if !c.isPersistent {
			runner.NewCmdRunner(cf.Cf("delete-org", "-f", c.organizationName), c.longTimeout).Run()

			cf.ApiRequest(
				"DELETE",
				"/v2/quota_definitions/"+c.quotaDefinitionGUID+"?recursive=true",
				nil,
				c.ShortTimeout(),
			)
		}

		if c.config.CreatePermissiveSecurityGroup {
			runner.NewCmdRunner(cf.Cf("delete-security-group", "-f", c.securityGroupName), c.shortTimeout).Run()
		}
	})
}
Exemple #19
0
func (context *ConfiguredContext) Setup() {
	cf.AsUser(context.AdminUserContext(), context.shortTimeout, func() {
		definition := quotaDefinition{
			Name: context.quotaDefinitionName,

			TotalServices: "100",
			TotalRoutes:   "1000",
			MemoryLimit:   "10G",

			NonBasicServicesAllowed: true,
		}

		args := []string{
			"create-quota",
			context.quotaDefinitionName,
			"-m", definition.MemoryLimit,
			"-r", definition.TotalRoutes,
			"-s", definition.TotalServices,
		}
		if definition.NonBasicServicesAllowed {
			args = append(args, "--allow-paid-service-plans")
		}

		runner.NewCmdRunner(cf.Cf(args...), context.shortTimeout).Run()

		if !context.config.UseExistingUser {
			createUserCmd := cf.Cf("create-user", context.regularUserUsername, context.regularUserPassword)
			runner.NewCmdRunner(createUserCmd, context.shortTimeout).Run()
			if createUserCmd.ExitCode() != 0 {
				Expect(createUserCmd.Out).To(Say("scim_resource_already_exists"))
			}
		}

		runner.NewCmdRunner(cf.Cf("create-org", context.organizationName), context.shortTimeout).Run()
		runner.NewCmdRunner(cf.Cf("set-quota", context.organizationName, definition.Name), context.shortTimeout).Run()
	})
}
func SetupEnvironment(context SuiteContext) {
	var originalCfHomeDir, currentCfHomeDir string

	BeforeEach(func() {
		AdminUserContext = context.AdminUserContext()
		RegularUserContext = context.RegularUserContext()

		context.Setup()

		cf.AsUser(AdminUserContext, func() {
			setUpSpaceWithUserAccess(RegularUserContext)
		})

		originalCfHomeDir, currentCfHomeDir = cf.InitiateUserContext(RegularUserContext)
		cf.TargetSpace(RegularUserContext)

	})

	AfterEach(func() {
		cf.RestoreUserContext(RegularUserContext, originalCfHomeDir, currentCfHomeDir)

		context.Teardown()
	})
}
		var output []byte
		var oldServiceName string
		var oldPlanName string

		BeforeEach(func() {
			broker = NewServiceBroker(
				generator.PrefixedRandomName("pblc-brkr-"),
				assets.NewAssets().ServiceBroker,
				context,
			)
			cf.TargetSpace(context.RegularUserContext(), context.ShortTimeout())
			broker.Push()
			broker.Configure()

			cf.AsUser(context.AdminUserContext(), context.ShortTimeout(), func() {
				broker.Create()
			})
		})

		Describe("Updating the catalog", func() {

			BeforeEach(func() {
				broker.PublicizePlans()
			})

			It("updates the broker and sees catalog changes", func() {
				// Confirming plans show up in the marketplace for regular user
				plans := cf.Cf("marketplace").Wait(DEFAULT_TIMEOUT)
				Expect(plans).To(Exit(0))
				Expect(plans).To(Say(broker.Service.Name))
		rules := fmt.Sprintf(
			`[{"destination":"%s","ports":"%d","protocol":"tcp"},
        {"destination":"%s","ports":"%d","protocol":"tcp"}]`,
			privateHost, privatePort, containerIp, privatePort)

		file, _ := ioutil.TempFile(os.TempDir(), "CATS-sg-rules")
		defer os.Remove(file.Name())
		file.WriteString(rules)

		rulesPath := file.Name()
		securityGroupName = fmt.Sprintf("CATS-SG-%s", generator.RandomName())

		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("create-security-group", securityGroupName, rulesPath).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			Expect(
				cf.Cf("bind-security-group",
					securityGroupName,
					context.RegularUserContext().Org,
					context.RegularUserContext().Space).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
		defer func() {
			cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
				Expect(cf.Cf("delete-security-group", securityGroupName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			})
		}()

		Expect(cf.Cf("restart", clientAppName).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))

		By("Testing app egress rules")
		curlResponse = helpers.CurlApp(clientAppName, fmt.Sprintf("/curl/%s/%d", privateHost, privatePort))
		json.Unmarshal([]byte(curlResponse), &doraCurlResponse)
		Expect(doraCurlResponse.ReturnCode).To(Equal(0))
	BeforeEach(func() {
		appName = generator.PrefixedRandomName("CATS-APP-")
		spaceGuid = GetSpaceGuidFromName(context.RegularUserContext().Space)
		appGuid = CreateApp(appName, spaceGuid, "{}")
		packageGuid = CreatePackage(appGuid)
		token = GetAuthToken()
		uploadUrl := fmt.Sprintf("%s/v3/packages/%s/upload", config.ApiEndpoint, packageGuid)
		UploadPackage(uploadUrl, assets.NewAssets().DoraZip, token)
		WaitForPackageToBeReady(packageGuid)

		buildpackName = generator.PrefixedRandomName("CATS-BP-")
		buildpackZip := createBuildpack()

		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("create-buildpack", buildpackName, buildpackZip, "999").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
	})

	AfterEach(func() {
		app_helpers.AppReport(appName, DEFAULT_TIMEOUT)

		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("delete-buildpack", buildpackName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
		DeleteApp(appGuid)
	})

	It("Stages with a user specified admin buildpack", func() {
		StagePackage(packageGuid, fmt.Sprintf(`{"lifecycle":{ "type": "buildpack", "data": { "buildpack": "%s" } }}`, buildpackName))
func (b ServiceBroker) Update() {
	cf.AsUser(b.context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		Expect(cf.Cf("update-service-broker", b.Name, "username", "password", helpers.AppUri(b.Name, "")).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})
}
func (b ServiceBroker) EnableServiceAccess() {
	cf.AsUser(b.context.AdminUserContext(), b.context.ShortTimeout(), func() {
		session := cf.Cf("enable-service-access", b.Service.Name).Wait(DEFAULT_TIMEOUT)
		Expect(session).To(Exit(0))
	})
}
		return buildpackArchivePath
	}

	var originalRunningEnv string
	var originalStagingEnv string
	var appName string
	var buildpackName string

	BeforeEach(func() {
		appName = generator.PrefixedRandomName("CATS-APP-")
		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			session := cf.Cf("curl", "/v2/config/environment_variable_groups/running").Wait(DEFAULT_TIMEOUT)
			Expect(session).To(Exit(0))
			originalRunningEnv = string(session.Out.Contents())

			session = cf.Cf("curl", "/v2/config/environment_variable_groups/staging").Wait(DEFAULT_TIMEOUT)
			Expect(session).To(Exit(0))
			originalStagingEnv = string(session.Out.Contents())
		})
	})

	AfterEach(func() {
		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("curl", "/v2/config/environment_variable_groups/staging", "-X", "PUT", "-d", originalStagingEnv).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			Expect(cf.Cf("curl", "/v2/config/environment_variable_groups/running", "-X", "PUT", "-d", originalRunningEnv).Wait(DEFAULT_TIMEOUT)).To(Exit(0))

			if buildpackName != "" {
				Expect(cf.Cf("delete-buildpack", buildpackName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			}
		})
	. "github.com/cloudfoundry/cf-acceptance-tests/helpers/services"
)

var _ = Describe("Purging service offerings", func() {
	var broker ServiceBroker

	BeforeEach(func() {
		broker = NewServiceBroker(
			generator.PrefixedRandomName("ps-"),
			assets.NewAssets().ServiceBroker,
			context,
		)
		broker.Push()
		broker.Configure()
		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			broker.Create()
			broker.PublicizePlans()
		})
	})

	AfterEach(func() {
		app_helpers.AppReport(broker.Name, DEFAULT_TIMEOUT)

		broker.Destroy()
	})

	Context("when there are several existing service entities", func() {
		var appName, instanceName, asyncInstanceName string

		BeforeEach(func() {
			appName = generator.PrefixedRandomName("CATS-APP-ps-")
			instanceName = generator.PrefixedRandomName("CATS-APP-ps-")
	curlRoute := func(hostName string, path string) string {
		uri := config.Protocol() + hostName + "." + domainName + path
		curlCmd := runner.Curl(uri)

		runner.NewCmdRunner(curlCmd, DEFAULT_TIMEOUT).Run()
		Expect(string(curlCmd.Err.Contents())).To(HaveLen(0))
		return string(curlCmd.Out.Contents())
	}

	BeforeEach(func() {
		orgName = context.RegularUserContext().Org
		spaceName = context.RegularUserContext().Space

		domainName = generator.RandomName() + "." + helpers.LoadConfig().AppsDomain
		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("create-shared-domain", domainName).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
		})

		appNameDora = generator.PrefixedRandomName("CATS-APP-")
		Expect(cf.Cf("push", appNameDora, "-m", "128M", "-p", assets.NewAssets().Dora, "-d", config.AppsDomain).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))

		appNameSimple = generator.PrefixedRandomName("CATS-APP-")
		Expect(cf.Cf("push", appNameSimple, "-m", "128M", "-p", assets.NewAssets().HelloWorld, "-d", config.AppsDomain).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
	})

	AfterEach(func() {
		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("target", "-o", orgName).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
			Expect(cf.Cf("delete-shared-domain", domainName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
Exemple #29
0
	var FakeCf = func(args ...string) *gexec.Session {
		FakeCfCalls = append(FakeCfCalls, args)
		var session, _ = gexec.Start(exec.Command("echo", "nothing"), nil, nil)
		return session
	}
	var user cf.UserContext

	BeforeEach(func() {
		FakeCfCalls = [][]string{}
		cf.Cf = FakeCf
		user = cf.NewUserContext("http://FAKE_API.example.com", "FAKE_USERNAME", "FAKE_PASSWORD", "FAKE_ORG", "FAKE_SPACE", true)
	})

	It("calls cf api", func() {
		cf.AsUser(user, FakeThingsToRunAsUser)

		Expect(FakeCfCalls[0]).To(Equal([]string{"api", "http://FAKE_API.example.com", "--skip-ssl-validation"}))
	})

	It("calls cf auth", func() {
		cf.AsUser(user, FakeThingsToRunAsUser)

		Expect(FakeCfCalls[1]).To(Equal([]string{"auth", "FAKE_USERNAME", "FAKE_PASSWORD"}))
	})

	Describe("calling cf target", func() {
		Context("when org is set and space is set", func() {
			It("includes flags to set org and space", func() {
				cf.AsUser(user, FakeThingsToRunAsUser)
	})

	It("removes all instances and plans of the service, then removes the service offering", func() {
		instanceName := "purge-offering-instance"

		marketplace := cf.Cf("marketplace").Wait(DEFAULT_TIMEOUT)
		Expect(marketplace).To(Exit(0))
		Expect(marketplace).To(Say(broker.Plan.Name))

		broker.CreateServiceInstance(instanceName)

		services := cf.Cf("services").Wait(DEFAULT_TIMEOUT)
		Expect(marketplace).To(Exit(0))
		Expect(services).To(Say(instanceName))

		Expect(cf.Cf("delete", broker.Name, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))

		cf.AsUser(context.AdminUserContext(), func() {
			Expect(cf.Cf("purge-service-offering", broker.Service.Name, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})

		services = cf.Cf("services").Wait(DEFAULT_TIMEOUT)
		Expect(services).To(Exit(0))
		Expect(services.Out.Contents()).NotTo(ContainSubstring(instanceName)) //TODO: Say?

		marketplace = cf.Cf("marketplace").Wait(DEFAULT_TIMEOUT)
		Expect(marketplace).To(Exit(0))
		Expect(marketplace.Out.Contents()).NotTo(ContainSubstring(broker.Service.Name)) //TODO: Say?
	})
})