func runPushTests(appName, appUrl string, testConfig *smoke.Config) { if testConfig.SkipSSLValidation { Expect(runner.Curl("-k", appUrl).Wait(CF_TIMEOUT_IN_SECONDS)).To(Say("It just needed to be restarted!")) } else { Expect(runner.Curl(appUrl).Wait(CF_TIMEOUT_IN_SECONDS)).To(Say("It just needed to be restarted!")) } instances := 2 maxAttempts := 30 ExpectAppToScale(appName, instances) ExpectAllAppInstancesToStart(appName, instances, maxAttempts) ExpectAllAppInstancesToBeReachable(appUrl, instances, maxAttempts) if testConfig.Cleanup { Expect(cf.Cf("delete", appName, "-f", "-r").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) Eventually(func() *Session { appStatusSession := cf.Cf("app", appName) Expect(appStatusSession.Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(1)) return appStatusSession }, 5).Should(Say("not found")) Eventually(func() *Session { if testConfig.SkipSSLValidation { return runner.Curl("-k", appUrl).Wait(CF_TIMEOUT_IN_SECONDS) } else { return runner.Curl(appUrl).Wait(CF_TIMEOUT_IN_SECONDS) } }, 5).Should(Say("404")) } }
func (b ServiceBroker) Destroy() { workflowhelpers.AsUser(b.TestSetup.AdminUserContext(), Config.DefaultTimeoutDuration(), func() { Expect(cf.Cf("purge-service-offering", b.Service.Name, "-f").Wait(Config.DefaultTimeoutDuration())).To(Exit(0)) }) b.Delete() Expect(cf.Cf("delete", b.Name, "-f", "-r").Wait(Config.DefaultTimeoutDuration())).To(Exit(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)) }) }
func setUpSpaceWithUserAccess(uc cf.UserContext) { spaceSetupTimeout := 10.0 Expect(cf.Cf("create-space", "-o", uc.Org, uc.Space).Wait(spaceSetupTimeout)).To(Exit(0)) Expect(cf.Cf("set-space-role", uc.Username, uc.Org, uc.Space, "SpaceManager").Wait(spaceSetupTimeout)).To(Exit(0)) Expect(cf.Cf("set-space-role", uc.Username, uc.Org, uc.Space, "SpaceDeveloper").Wait(spaceSetupTimeout)).To(Exit(0)) Expect(cf.Cf("set-space-role", uc.Username, uc.Org, uc.Space, "SpaceAuditor").Wait(spaceSetupTimeout)).To(Exit(0)) }
func ScaleAppInstances(appName string, instances int) { Expect(cf.Cf("scale", appName, "-i", strconv.Itoa(instances)).Wait(DEFAULT_TIMEOUT)).To(Exit(0)) Eventually(func() string { return string(cf.Cf("app", appName).Wait(DEFAULT_TIMEOUT).Out.Contents()) }, DEFAULT_TIMEOUT*2, 2*time.Second). Should(ContainSubstring(fmt.Sprintf("instances: %d/%d", instances, instances))) }
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) 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)) }) }
func EnableDiego(appName string) { cfApp := cf.Cf("app", appName, "--guid") Expect(cfApp.Wait()).To(Exit(0)) appGuid := strings.TrimSpace(string(cfApp.Out.Contents())) Expect(appGuid).NotTo(Equal("")) Eventually(cf.Cf("curl", "/v2/apps/"+appGuid, "-X", "PUT", "-d", `{"diego": true}`)).Should(Exit(0)) }
func AppReport(appName string, timeout time.Duration) { if appName == "" { fmt.Println("App name was set to \"\"; skipping app report.") return } Eventually(cf.Cf("app", appName, "--guid"), timeout).Should(Exit()) Eventually(cf.Cf("logs", appName, "--recent"), timeout).Should(Exit()) }
func (b ServiceBroker) Delete() { workflowhelpers.AsUser(b.TestSetup.AdminUserContext(), Config.DefaultTimeoutDuration(), func() { Expect(cf.Cf("delete-service-broker", b.Name, "-f").Wait(Config.DefaultTimeoutDuration())).To(Exit(0)) brokers := cf.Cf("service-brokers").Wait(Config.DefaultTimeoutDuration()) Expect(brokers).To(Exit(0)) Expect(brokers.Out.Contents()).ToNot(ContainSubstring(b.Name)) }) }
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 (b ServiceBroker) CreateServiceInstance(instanceName string) string { Expect(cf.Cf("create-service", b.Service.Name, b.SyncPlans[0].Name, instanceName).Wait(DEFAULT_TIMEOUT)).To(Exit(0)) url := fmt.Sprintf("/v2/service_instances?q=name:%s", instanceName) serviceInstance := ServiceInstanceResponse{} curl := cf.Cf("curl", url).Wait(DEFAULT_TIMEOUT) Expect(curl).To(Exit(0)) json.Unmarshal(curl.Out.Contents(), &serviceInstance) return serviceInstance.Resources[0].Metadata.Guid }
func SetBackend(appName string) { config := helpers.LoadConfig() if config.Backend == "diego" { guid := guidForAppName(appName) Eventually(cf.Cf("curl", "/v2/apps/"+guid, "-X", "PUT", "-d", `{"diego": true}`), DEFAULT_TIMEOUT).Should(Exit(0)) } else if config.Backend == "dea" { guid := guidForAppName(appName) Eventually(cf.Cf("curl", "/v2/apps/"+guid, "-X", "PUT", "-d", `{"diego": false}`), DEFAULT_TIMEOUT).Should(Exit(0)) } }
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)) } }) }
func (b ServiceBroker) Push() { Expect(cf.Cf("push", b.Name, "-p", b.Path, "--no-start").Wait(BROKER_START_TIMEOUT)).To(Exit(0)) if helpers.LoadConfig().UseDiego { appGuid := strings.TrimSpace(string(cf.Cf("app", b.Name, "--guid").Wait(DEFAULT_TIMEOUT).Out.Contents())) cf.Cf("curl", fmt.Sprintf("/v2/apps/%s", appGuid), "-X", "PUT", "-d", "{\"diego\": true}", ).Wait(DEFAULT_TIMEOUT) } Expect(cf.Cf("start", b.Name).Wait(BROKER_START_TIMEOUT)).To(Exit(0)) }
func (b ServiceBroker) Push(config cats_config.CatsConfig) { Expect(cf.Cf( "push", b.Name, "--no-start", "-b", config.GetRubyBuildpackName(), "-m", DEFAULT_MEMORY_LIMIT, "-p", b.Path, "-d", config.GetAppsDomain(), ).Wait(Config.BrokerStartTimeoutDuration())).To(Exit(0)) app_helpers.SetBackend(b.Name) Expect(cf.Cf("start", b.Name).Wait(Config.BrokerStartTimeoutDuration())).To(Exit(0)) }
func TestSmokeTests(t *testing.T) { testConfig := smoke.GetConfig() testUserContext := cf.NewUserContext( testConfig.ApiEndpoint, testConfig.User, testConfig.Password, testConfig.Org, testConfig.Space, testConfig.SkipSSLValidation, ) RegisterFailHandler(Fail) cf.CF_API_TIMEOUT = CF_API_TIMEOUT_OVERRIDE var originalCfHomeDir, currentCfHomeDir string BeforeEach(func() { originalCfHomeDir, currentCfHomeDir = cf.InitiateUserContext(testUserContext) if !testConfig.UseExistingOrg { Expect(cf.Cf("create-quota", quotaName(testConfig.Org), "-m", "10G", "-r", "10", "-s", "2").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) Expect(cf.Cf("create-org", testConfig.Org).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) Expect(cf.Cf("set-quota", testConfig.Org, quotaName(testConfig.Org)).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) } Expect(cf.Cf("target", "-o", testConfig.Org).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) if !testConfig.UseExistingSpace { Expect(cf.Cf("create-space", "-o", testConfig.Org, testConfig.Space).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) } Expect(cf.Cf("target", "-s", testConfig.Space).Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) }) AfterEach(func() { if testConfig.Cleanup && !testConfig.UseExistingSpace { Expect(cf.Cf("delete-space", testConfig.Space, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) } if testConfig.Cleanup && !testConfig.UseExistingOrg { Expect(cf.Cf("delete-org", testConfig.Org, "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) Expect(cf.Cf("delete-quota", quotaName(testConfig.Org), "-f").Wait(CF_TIMEOUT_IN_SECONDS)).To(Exit(0)) } cf.RestoreUserContext(testUserContext, originalCfHomeDir, currentCfHomeDir) }) rs := []Reporter{} if testConfig.ArtifactsDirectory != "" { os.Setenv("CF_TRACE", traceLogFilePath(testConfig)) rs = append(rs, reporters.NewJUnitReporter(jUnitReportFilePath(testConfig))) } RunSpecsWithDefaultAndCustomReporters(t, "CF-Runtime-Smoke-Tests", rs) }
func (a *cfApp) VerifySsh(instanceIndex int) { envCmd := cf.Cf("ssh", a.appName, "-i", strconv.Itoa(instanceIndex), "-c", `"/usr/bin/env"`) Expect(envCmd.Wait()).To(gexec.Exit(0)) output := string(envCmd.Buffer().Contents()) Expect(string(output)).To(MatchRegexp(fmt.Sprintf(`VCAP_APPLICATION=.*"application_name":"%s"`, a.appName))) Expect(string(output)).To(MatchRegexp(fmt.Sprintf("INSTANCE_INDEX=%d", instanceIndex))) Eventually(cf.Cf("logs", a.appName, "--recent")).Should(gbytes.Say("Successful remote access")) Eventually(cf.Cf("events", a.appName)).Should(gbytes.Say("audit.app.ssh-authorized")) }
func getAppHostIpAndPort(appName string) (string, int) { var appsResponse AppsResponse cfResponse := cf.Cf("curl", fmt.Sprintf("/v2/apps?q=name:%s", appName)).Wait(Config.DefaultTimeoutDuration()).Out.Contents() json.Unmarshal(cfResponse, &appsResponse) serverAppUrl := appsResponse.Resources[0].Metadata.Url var statsResponse StatsResponse cfResponse = cf.Cf("curl", fmt.Sprintf("%s/stats", serverAppUrl)).Wait(Config.DefaultTimeoutDuration()).Out.Contents() json.Unmarshal(cfResponse, &statsResponse) return statsResponse["0"].Stats.Host, statsResponse["0"].Stats.Port }
func unbindRouteFromService(hostname, serviceInstanceName string) { routeGuid := getRouteGuid(hostname, "") guid := getServiceInstanceGuid(serviceInstanceName) cf.Cf("curl", fmt.Sprintf("/v2/service_instances/%s/routes/%s", guid, routeGuid), "-X", "DELETE") Eventually(func() string { response := cf.Cf("curl", fmt.Sprintf("/v2/routes/%s", routeGuid)) Expect(response.Wait(DEFAULT_TIMEOUT)).To(Exit(0)) contents := response.Out.Contents() return string(contents) }, DEFAULT_TIMEOUT, "1s").Should(ContainSubstring(`"service_instance_guid": null`)) }
func (b ServiceBroker) Push() { config := helpers.LoadConfig() Expect(cf.Cf( "push", b.Name, "--no-start", "-b", config.RubyBuildpackName, "-m", DEFAULT_MEMORY_LIMIT, "-p", b.Path, "-d", config.AppsDomain, ).Wait(BROKER_START_TIMEOUT)).To(Exit(0)) app_helpers.SetBackend(b.Name) Expect(cf.Cf("start", b.Name).Wait(BROKER_START_TIMEOUT)).To(Exit(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 targetedSpaceGuid() string { output := cf.Cf("target") Expect(output.Wait()).To(Exit(0)) targetInfo := strings.TrimSpace(string(output.Out.Contents())) spaceMatch, _ := regexp.Compile(`Space:\s+([^\s]+)`) spaceName := spaceMatch.FindAllStringSubmatch(targetInfo, -1)[0][1] output = cf.Cf("space", spaceName, "--guid") Expect(output.Wait()).To(Exit(0)) return strings.TrimSpace(string(output.Out.Contents())) }
func unbindRouteFromService(hostname, serviceInstanceName string) { routeGuid := GetRouteGuid(hostname, "", Config.DefaultTimeoutDuration()) Expect(cf.Cf("unbind-route-service", Config.GetAppsDomain(), serviceInstanceName, "-f", "--hostname", hostname, ).Wait(Config.DefaultTimeoutDuration())).To(Exit(0)) Eventually(func() string { response := cf.Cf("curl", fmt.Sprintf("/v2/routes/%s", routeGuid)) Expect(response.Wait(Config.DefaultTimeoutDuration())).To(Exit(0)) return string(response.Out.Contents()) }, Config.DefaultTimeoutDuration(), "1s").Should(ContainSubstring(`"service_instance_guid": null`)) }
func bindRouteToServiceWithParams(hostname, serviceInstanceName string, params string) { routeGuid := getRouteGuid(hostname, "") serviceInstanceGuid := getServiceInstanceGuid(serviceInstanceName) cf.Cf("curl", fmt.Sprintf("/v2/service_instances/%s/routes/%s", serviceInstanceGuid, routeGuid), "-X", "PUT", "-d", fmt.Sprintf("{\"parameters\": %s}", params)) Eventually(func() string { response := cf.Cf("curl", fmt.Sprintf("/v2/routes/%s", routeGuid)) Expect(response.Wait(DEFAULT_TIMEOUT)).To(Exit(0)) contents := response.Out.Contents() return string(contents) }, DEFAULT_TIMEOUT, "1s").ShouldNot(ContainSubstring(`"service_instance_guid": null`)) }
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 (c context) createPermissiveSecurityGroup() { rules := []map[string]string{ map[string]string{ "destination": "0.0.0.0-255.255.255.255", "protocol": "all", }, } rulesFilePath, err := c.writeJSONToTempFile(rules, fmt.Sprintf("%s-rules.json", c.securityGroupName)) defer os.RemoveAll(rulesFilePath) gomega.Expect(err).ToNot(gomega.HaveOccurred()) runner.NewCmdRunner(cf.Cf("create-security-group", c.securityGroupName, rulesFilePath), c.shortTimeout).Run() runner.NewCmdRunner(cf.Cf("bind-security-group", c.securityGroupName, c.organizationName, c.spaceName), c.shortTimeout).Run() }
func GetAppInfo(appName string) (host, port string) { var appsResponse AppsResponse var statsResponse StatsResponse cfResponse := cf.Cf("curl", fmt.Sprintf("/v2/apps?q=name:%s", appName)).Wait(DEFAULT_TIMEOUT).Out.Contents() json.Unmarshal(cfResponse, &appsResponse) serverAppUrl := appsResponse.Resources[0].Metadata.Url cfResponse = cf.Cf("curl", fmt.Sprintf("%s/stats", serverAppUrl)).Wait(DEFAULT_TIMEOUT).Out.Contents() json.Unmarshal(cfResponse, &statsResponse) appIp := statsResponse["0"].Stats.Host appPort := fmt.Sprintf("%d", statsResponse["0"].Stats.Port) return appIp, appPort }
func pushApp() string { appName := generator.PrefixedRandomName("LATS-App-") appPush := cf.Cf("push", appName, "-p", "assets/dora").Wait(60 * time.Second) Expect(appPush).To(gexec.Exit(0)) return appName }