func configureBroker(serviceBrokerAppName, routeServiceName string) { brokerConfigJson := helpers.CurlApp(serviceBrokerAppName, "/config") var brokerConfigMap customMap err := json.Unmarshal([]byte(brokerConfigJson), &brokerConfigMap) Expect(err).NotTo(HaveOccurred()) if routeServiceName != "" { routeServiceUrl := helpers.AppUri(routeServiceName, "/") url, err := url.Parse(routeServiceUrl) Expect(err).NotTo(HaveOccurred()) url.Scheme = "https" routeServiceUrl = url.String() brokerConfigMap.key("behaviors").key("bind").key("default").key("body")["route_service_url"] = routeServiceUrl } else { body := brokerConfigMap.key("behaviors").key("bind").key("default").key("body") delete(body, "route_service_url") } changedJson, err := json.Marshal(brokerConfigMap) Expect(err).NotTo(HaveOccurred()) helpers.CurlApp(serviceBrokerAppName, "/config", "-X", "POST", "-d", string(changedJson)) }
func initiateBrokerConfig(serviceBrokerAppName string) string { brokerConfigJson := helpers.CurlApp(serviceBrokerAppName, "/config") var brokerConfigMap customMap err := json.Unmarshal([]byte(brokerConfigJson), &brokerConfigMap) Expect(err).NotTo(HaveOccurred()) dashboardClientId := generator.PrefixedRandomName("RATS-DASHBOARD-ID-") serviceName := generator.PrefixedRandomName("RATS-SERVICE-") serviceId := generator.PrefixedRandomName("RATS-SERVICE-ID-") services := brokerConfigMap.key("behaviors").key("catalog").key("body")["services"].([]interface{}) service := services[0].(map[string]interface{}) service["dashboard_client"].(map[string]interface{})["id"] = dashboardClientId service["name"] = serviceName service["id"] = serviceId plans := service["plans"].([]interface{}) for i, plan := range plans { servicePlanId := generator.PrefixedRandomName(fmt.Sprintf("RATS-SERVICE-PLAN-ID-%d-", i)) plan.(map[string]interface{})["id"] = servicePlanId } changedJson, err := json.Marshal(brokerConfigMap) Expect(err).NotTo(HaveOccurred()) helpers.CurlApp(serviceBrokerAppName, "/config", "-X", "POST", "-d", string(changedJson)) return serviceName }
func getAppContainerIpAndPort(appName string) (string, int) { curlResponse := helpers.CurlApp(Config, appName, "/myip") containerIp := strings.TrimSpace(curlResponse) curlResponse = helpers.CurlApp(Config, appName, "/env/VCAP_APPLICATION") var env map[string]interface{} err := json.Unmarshal([]byte(curlResponse), &env) Expect(err).NotTo(HaveOccurred()) containerPort := int(env["port"].(float64)) return containerIp, containerPort }
func curlAppHeaders(appName, path string, args ...string) textproto.MIMEHeader { curlResponse := helpers.CurlApp(appName, path, append(args, "-I")...) reader := textproto.NewReader(bufio.NewReader(bytes.NewBufferString(curlResponse))) reader.ReadLine() m, err := reader.ReadMIMEHeader() Expect(err).ShouldNot(HaveOccurred()) return m }
Expect(cf.Cf( "push", appName, "--no-start", "-b", config.RubyBuildpackName, "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().Dora, "-d", helpers.LoadConfig().AppsDomain, "-c", "FOO=foo bundle exec rackup config.ru -p $PORT", ).Wait(DEFAULT_TIMEOUT)).To(Exit(0)) app_helpers.SetBackend(appName) Expect(cf.Cf("start", appName).Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) }) It("takes effect after a restart, not requiring a push", func() { Eventually(func() string { return helpers.CurlApp(appName, "/env/FOO") }, DEFAULT_TIMEOUT).Should(ContainSubstring("foo")) var response cf.QueryResponse cf.ApiRequest("GET", "/v2/apps?q=name:"+appName, &response, DEFAULT_TIMEOUT) Expect(response.Resources).To(HaveLen(1)) appGuid := response.Resources[0].Metadata.Guid cf.ApiRequest( "PUT", "/v2/apps/"+appGuid, nil, DEFAULT_TIMEOUT,
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" ) var _ = Describe(deaUnsupportedTag+"Docker Application Lifecycle", func() { var appName string JustBeforeEach(func() { app_helpers.SetBackend(appName) By("downloading from dockerhub (starting the app)") Eventually(cf.Cf("start", appName), CF_PUSH_TIMEOUT).Should(Exit(0)) Eventually(func() string { return helpers.CurlApp(appName, "/env/INSTANCE_INDEX") }, DEFAULT_TIMEOUT).Should(Equal("0")) }) AfterEach(func() { app_helpers.AppReport(appName, DEFAULT_TIMEOUT) Eventually(cf.Cf("delete", appName, "-f"), DEFAULT_TIMEOUT).Should(Exit(0)) }) Describe("running a docker app with a start command", func() { BeforeEach(func() { appName = generator.PrefixedRandomName("CATS-APP-") Eventually(cf.Cf( "push", appName, "--no-start", // app is defined by cloudfoundry-incubator/diego-dockerfiles
package wats import ( "github.com/cloudfoundry-incubator/cf-test-helpers/helpers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Application Lifecycle", func() { Describe("An app staged on Diego and running on Diego", func() { It("exercises the app through its lifecycle", func() { By("pushing it") Eventually(pushNoraWithOptions(appName, 1, "256m"), CF_PUSH_TIMEOUT).Should(Succeed()) By("staging and running it on Diego") enableDiego(appName) Eventually(runCf("start", appName), CF_PUSH_TIMEOUT).Should(Succeed()) By("attempting to leak more memory than allowed") // leak 300mb response := helpers.CurlApp(appName, "/leakmemory/300") Expect(response).To(ContainSubstring("Insufficient memory")) }) }) })
AfterEach(func() { Expect(cf.Cf("delete", serverAppName, "-f").Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) }) // this test assumes the default running security groups block access to the DEAs // the test takes advantage of the fact that the DEA ip address and internal container ip address // are discoverable via the cc api and dora's myip endpoint It("allows previously-blocked ip traffic after applying a security group, and re-blocks it when the group is removed", func() { clientAppName := generator.PrefixedRandomName("CATS-APP-") Expect(cf.Cf("push", clientAppName, "-m", "128M", "-p", assets.NewAssets().Dora, "-d", config.AppsDomain).Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) defer func() { cf.Cf("delete", clientAppName, "-f").Wait(CF_PUSH_TIMEOUT) }() By("Gathering container ip") curlResponse := helpers.CurlApp(serverAppName, "/myip") containerIp := strings.TrimSpace(curlResponse) By("Testing app egress rules") var doraCurlResponse DoraCurlResponse curlResponse = helpers.CurlApp(clientAppName, fmt.Sprintf("/curl/%s/%d", privateHost, privatePort)) json.Unmarshal([]byte(curlResponse), &doraCurlResponse) Expect(doraCurlResponse.ReturnCode).ToNot(Equal(0)) By("Applying security group") 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")
if process.Type == "web" { webProcess = process } else if process.Type == "worker" { workerProcess = process } } CreateAndMapRoute(appGuid, context.RegularUserContext().Space, helpers.LoadConfig().AppsDomain, webProcess.Name) StartApp(appGuid) Eventually(func() string { return helpers.CurlAppRoot(webProcess.Name) }, DEFAULT_TIMEOUT).Should(ContainSubstring("Hi, I'm Dora!")) output := helpers.CurlApp(webProcess.Name, "/env") Expect(output).To(ContainSubstring(fmt.Sprintf("application_name\\\":\\\"%s", appName))) Expect(output).To(ContainSubstring(appCreationEnvironmentVariables)) Expect(cf.Cf("apps").Wait(DEFAULT_TIMEOUT)).To(Say(fmt.Sprintf("%s\\s+started", webProcess.Name))) Expect(cf.Cf("apps").Wait(DEFAULT_TIMEOUT)).To(Say(fmt.Sprintf("%s\\s+started", workerProcess.Name))) usageEvents := lastPageUsageEvents(appName) event1 := AppUsageEvent{Entity{ProcessType: webProcess.Type, AppGuid: webProcess.Guid, State: "STARTED", ParentAppGuid: appGuid, ParentAppName: appName}} event2 := AppUsageEvent{Entity{ProcessType: workerProcess.Type, AppGuid: workerProcess.Guid, State: "STARTED", ParentAppGuid: appGuid, ParentAppName: appName}} Expect(eventsInclude(usageEvents, event1)).To(BeTrue()) Expect(eventsInclude(usageEvents, event2)).To(BeTrue()) StopApp(appGuid)
BeforeEach(func() { appName = generator.PrefixedRandomName("CATS-APP-") Expect(cf.Cf("push", appName, "--no-start", "-b", config.RubyBuildpackName, "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().Dora, "-d", config.AppsDomain).Wait(DEFAULT_TIMEOUT)).To(Exit(0)) app_helpers.SetBackend(appName) Expect(cf.Cf("start", appName).Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) }) AfterEach(func() { app_helpers.AppReport(appName, DEFAULT_TIMEOUT) Expect(cf.Cf("delete", appName, "-f", "-r").Wait(DEFAULT_TIMEOUT)).Should(Exit(0)) }) It("doesn't die when printing 32MB", func() { beforeId := helpers.CurlApp(appName, "/id") Expect(helpers.CurlAppWithTimeout(appName, "/logspew/32000", LONG_CURL_TIMEOUT)). To(ContainSubstring("Just wrote 32000 kbytes to the log")) // Give time for components (i.e. Warden) to react to the output // and potentially make bad decisions (like killing the app) time.Sleep(10 * time.Second) afterId := helpers.CurlApp(appName, "/id") Expect(beforeId).To(Equal(afterId)) }) })
package wats import ( "github.com/cloudfoundry-incubator/cf-test-helpers/cf" "github.com/cloudfoundry-incubator/cf-test-helpers/helpers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" ) var _ = Describe("A running application", func() { BeforeEach(func() { pushAndStartNora(appName) }) AfterEach(func() { Eventually(cf.Cf("logs", appName, "--recent")).Should(gexec.Exit()) Eventually(cf.Cf("delete", appName, "-f")).Should(gexec.Exit(0)) }) It("can show crash events", func() { helpers.CurlApp(appName, "/exit") Eventually(func() string { return string(cf.Cf("events", appName).Wait(CF_PUSH_TIMEOUT).Out.Contents()) }, CF_PUSH_TIMEOUT).Should(ContainSubstring("Exited")) }) })
BeforeEach(func() { appName = generator.PrefixedRandomName("CATS-APP-") Expect(cf.Cf("push", appName, "-p", assets.NewAssets().Java, "--no-start", "-m", "512M").Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) Expect(cf.Cf("set-env", appName, "JAVA_OPTS", "-Djava.security.egd=file:///dev/urandom").Wait(DEFAULT_TIMEOUT)).To(Exit(0)) Expect(cf.Cf("start", appName).Wait(CF_JAVA_TIMEOUT)).To(Exit(0)) }) AfterEach(func() { Expect(cf.Cf("delete", appName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0)) }) It("Does not corrupt UTF-8 characters in filenames", func() { var curlResponse string Eventually(func() string { curlResponse = helpers.CurlApp(appName, "/omega") return curlResponse }, DEFAULT_TIMEOUT).Should(ContainSubstring("It's Ω!")) Expect(curlResponse).To(ContainSubstring("File encoding is UTF-8")) }) Describe("Routing", func() { It("Supports URLs with percent-encoded characters", func() { var curlResponse string Eventually(func() string { curlResponse = helpers.CurlApp(appName, "/requesturi/%21%7E%5E%24%20%27%28%29?foo=bar+baz%20bing") return curlResponse }, DEFAULT_TIMEOUT).Should(ContainSubstring("You requested some information about rio rancho properties")) Expect(curlResponse).To(ContainSubstring("/requesturi/%21%7E%5E%24%20%27%28%29")) Expect(curlResponse).To(ContainSubstring("Query String is [foo=bar+baz%20bing]")) })
MapRouteToApp(domain, app2Path, app2) MapRouteToApp(domain, app3Path, app3) }) AfterEach(func() { app_helpers.AppReport(app1, DEFAULT_TIMEOUT) app_helpers.AppReport(app2, DEFAULT_TIMEOUT) app_helpers.AppReport(app3, DEFAULT_TIMEOUT) DeleteApp(app1) DeleteApp(app2) DeleteApp(app3) }) Context("when another app has a route with a context path", func() { It("routes to app with context path", func() { Eventually(func() string { return helpers.CurlAppRoot(domain) }, DEFAULT_TIMEOUT).Should(ContainSubstring(app1)) Eventually(func() string { return helpers.CurlApp(domain, app2Path) }, DEFAULT_TIMEOUT).Should(ContainSubstring(app2)) Eventually(func() string { return helpers.CurlApp(domain, app3Path) }, DEFAULT_TIMEOUT).Should(ContainSubstring(app3)) }) }) })
appName = random_name.CATSRandomName("APP") envVarName = fmt.Sprintf("CATS_RUNNING_TEST_VAR_%s", strconv.Itoa(int(time.Now().UnixNano()))) }) AfterEach(func() { app_helpers.AppReport(appName, Config.DefaultTimeoutDuration()) workflowhelpers.AsUser(TestSetup.AdminUserContext(), Config.DefaultTimeoutDuration(), func() { revertExtendedEnv("running", envVarName) }) Expect(cf.Cf("delete", appName, "-f", "-r").Wait(Config.CfPushTimeoutDuration())).To(Exit(0)) }) It("Applies correct environment variables while running apps", func() { envVarValue := fmt.Sprintf("running_env_value_%s", strconv.Itoa(int(time.Now().UnixNano()))) workflowhelpers.AsUser(TestSetup.AdminUserContext(), Config.DefaultTimeoutDuration(), func() { extendEnv("running", envVarName, envVarValue) }) Expect(cf.Cf("push", appName, "--no-start", "-b", Config.GetRubyBuildpackName(), "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().Dora, "-d", Config.GetAppsDomain()).Wait(Config.DefaultTimeoutDuration())).To(Exit(0)) app_helpers.SetBackend(appName) Expect(cf.Cf("start", appName).Wait(Config.CfPushTimeoutDuration())).To(Exit(0)) env := helpers.CurlApp(Config, appName, "/env") Expect(env).To(ContainSubstring(envVarValue)) }) }) })
return session }, 1*time.Minute, 10*time.Second).Should(Say("my-service")) }) }) // TODO Unpend this test once v3 service bindings can be deleted (especially recursively through org delete) PIt("exposes them during running", func() { dropletGuid := StagePackage(packageGuid, "{}") WaitForDropletToStage(dropletGuid) AssignDropletToApp(appGuid, dropletGuid) CreateAndMapRoute(appGuid, context.RegularUserContext().Space, config.AppsDomain, appName) StartApp(appGuid) Eventually(func() string { return helpers.CurlApp(appName, "/env") }, DEFAULT_TIMEOUT).Should(ContainSubstring("my-service")) }) }) func createEnvBuildpack() string { tmpPath, err := ioutil.TempDir("", "buildpack-cats") Expect(err).ToNot(HaveOccurred()) buildpackArchivePath := path.Join(tmpPath, "buildpack.zip") archive_helpers.CreateZipArchive(buildpackArchivePath, []archive_helpers.ArchiveFile{ { Name: "bin/compile", Body: `#!/usr/bin/env bash
appLogsSession := cf.Cf("logs", "--recent", app1) Eventually(appLogsSession.Out, "5s").Should(gbytes.Say("x_b3_traceid")) _, _, parentSpanId := grabIDs(string(appLogsSession.Out.Contents()), "") Expect(parentSpanId).To(Equal("-")) By("when request has zipkin trace headers") traceId := "fee1f7ba6aeec41c" header1 := fmt.Sprintf(`X-B3-TraceId: %s `, traceId) header2 := `X-B3-SpanId: 579b36fd31cd8714` Eventually(func() string { curlOutput = cf_helpers.CurlApp(Config, hostname, "/", "-H", header1, "-H", header2) return curlOutput }, Config.DefaultTimeoutDuration()).Should(ContainSubstring("parents:")) appLogsSession = cf.Cf("logs", "--recent", hostname) Eventually(appLogsSession.Out).Should(gbytes.Say("x_b3_traceid:\"fee1f7ba6aeec41c")) _, appLogSpanId, _ := grabIDs(string(appLogsSession.Out.Contents()), traceId) Expect(curlOutput).To(ContainSubstring(traceId)) Expect(curlOutput).To(ContainSubstring(fmt.Sprintf("parents: [%s]", appLogSpanId))) }) }) }) })
Eventually(cf.Cf("push", appName, "-p", assets.NewAssets().Dora, "--no-start", "-b", "ruby_buildpack"), CF_PUSH_TIMEOUT).Should(Exit(0)) By("staging and running it on Diego") enableDiego(appName) Eventually(cf.Cf("start", appName), CF_PUSH_TIMEOUT).Should(Exit(0)) By("verifying it's up") Eventually(helpers.CurlingAppRoot(appName)).Should(ContainSubstring("Hi, I'm Dora!")) secureAddress := helpers.LoadConfig().SecureAddress secureHost, securePort, err := net.SplitHostPort(secureAddress) Expect(err).NotTo(HaveOccurred()) // test app egress rules var doraCurlResponse DoraCurlResponse curlResponse := helpers.CurlApp(appName, fmt.Sprintf("/curl/%s/%s", secureHost, securePort)) json.Unmarshal([]byte(curlResponse), &doraCurlResponse) Expect(doraCurlResponse.ReturnCode).NotTo(Equal(0)) firstCurlError := doraCurlResponse.ReturnCode // apply security group rules := fmt.Sprintf(`[{"destination":"%s","ports":"%s","protocol":"tcp"}]`, secureHost, securePort) file, _ := ioutil.TempFile(os.TempDir(), "DATS-sg-rules") defer os.Remove(file.Name()) file.WriteString(rules) file.Close() rulesPath := file.Name() securityGroupName := fmt.Sprintf("DATS-SG-%s", generator.RandomName())
Eventually(helpers.CurlingAppRoot(appName)).Should(ContainSubstring("Hi, I'm Dora!")) }) It("captures logs with the correct tag", func() { var message string var logs *Session By("logging health checks") logs = cf.Cf("logs", appName, "--recent") Eventually(logs).Should(Exit(0)) Expect(logs.Out).To(Say("\\[HEALTH/0\\]\\s+OUT healthcheck passed")) Expect(logs.Out).To(Say("\\[HEALTH/0\\]\\s+OUT Exit status 0")) By("logging application stdout") message = "A message from stdout" Eventually(helpers.CurlApp(appName, fmt.Sprintf("/echo/stdout/%s", url.QueryEscape(message)))).Should(ContainSubstring(message)) logs = cf.Cf("logs", appName, "--recent") Eventually(logs).Should(Exit(0)) Expect(logs.Out).To(Say(fmt.Sprintf("\\[APP/0\\]\\s+OUT %s", message))) By("logging application stderr") message = "A message from stderr" Eventually(helpers.CurlApp(appName, fmt.Sprintf("/echo/stderr/%s", url.QueryEscape(message)))).Should(ContainSubstring(message)) logs = cf.Cf("logs", appName, "--recent") Eventually(logs).Should(Exit(0)) Expect(logs.Out).To(Say(fmt.Sprintf("\\[APP/0\\]\\s+ERR %s", message))) }) }) })
if buildpackName != "" { Expect(cf.Cf("delete-buildpack", buildpackName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0)) } }) Expect(cf.Cf("delete", appName, "-f").Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) }) It("Applies correct environment variables while running apps", func() { cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() { Expect(cf.Cf("set-running-environment-variable-group", `{"CATS_RUNNING_TEST_VAR":"running_env_value"}`).Wait(DEFAULT_TIMEOUT)).To(Exit(0)) }) Expect(cf.Cf("push", appName, "-m", "128M", "-p", assets.NewAssets().Dora, "-d", config.AppsDomain).Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) env := helpers.CurlApp(appName, "/env") Expect(env).To(ContainSubstring("running_env_value")) }) It("Applies environment variables while staging apps", func() { buildpackName = generator.RandomName() buildpackZip := createBuildpack() cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() { Expect(cf.Cf("set-staging-environment-variable-group", `{"CATS_STAGING_TEST_VAR":"staging_env_value"}`).Wait(DEFAULT_TIMEOUT)).To(Exit(0)) Expect(cf.Cf("create-buildpack", buildpackName, buildpackZip, "999").Wait(DEFAULT_TIMEOUT)).To(Exit(0)) }) Expect(cf.Cf("push", appName, "-m", "128M", "-b", buildpackName, "-p", assets.NewAssets().HelloWorld, "-d", config.AppsDomain).Wait(CF_PUSH_TIMEOUT)).To(Exit(1))
payload := fmt.Sprintf(createDockerAppPayload, appName, spaceGuid) Eventually(cf.Cf("curl", "/v2/apps", "-X", "POST", "-d", payload)).Should(Exit(0)) Eventually(cf.Cf("create-route", context.RegularUserContext().Space, domain, "-n", appName)).Should(Exit(0)) Eventually(cf.Cf("map-route", appName, domain, "-n", appName)).Should(Exit(0)) Eventually(cf.Cf("start", appName), DOCKER_IMAGE_DOWNLOAD_DEFAULT_TIMEOUT).Should(Exit(0)) Eventually(helpers.CurlingAppRoot(appName)).Should(Equal("0")) }) AfterEach(func() { Eventually(cf.Cf("logs", appName, "--recent")).Should(Exit()) Eventually(cf.Cf("delete", appName, "-f")).Should(Exit(0)) }) Describe("running the app", func() { It("merges the garden and docker environment variables", func() { env_json := helpers.CurlApp(appName, "/env") var env_vars map[string]string json.Unmarshal([]byte(env_json), &env_vars) // garden set values should win Expect(env_vars).To(HaveKey("HOME")) Expect(env_vars).NotTo(HaveKeyWithValue("HOME", "/home/some_docker_user")) Expect(env_vars).To(HaveKey("VCAP_APPLICATION")) Expect(env_vars).NotTo(HaveKeyWithValue("VCAP_APPLICATION", "{}")) // docker image values should remain Expect(env_vars).To(HaveKeyWithValue("SOME_VAR", "some_docker_value")) Expect(env_vars).To(HaveKeyWithValue("BAD_QUOTE", "'")) Expect(env_vars).To(HaveKeyWithValue("BAD_SHELL", "$1")) }) })
var _ = DockerDescribe("Docker Application Lifecycle", func() { var appName string BeforeEach(func() { if Config.GetBackend() != "diego" { Skip(skip_messages.SkipDiegoMessage) } }) JustBeforeEach(func() { app_helpers.SetBackend(appName) By("downloading from dockerhub (starting the app)") Eventually(cf.Cf("start", appName), Config.CfPushTimeoutDuration()).Should(Exit(0)) Eventually(func() string { return helpers.CurlApp(Config, appName, "/env/INSTANCE_INDEX") }, Config.DefaultTimeoutDuration()).Should(Equal("0")) }) AfterEach(func() { app_helpers.AppReport(appName, Config.DefaultTimeoutDuration()) Eventually(cf.Cf("delete", appName, "-f"), Config.DefaultTimeoutDuration()).Should(Exit(0)) }) Describe("running a docker app with a start command", func() { BeforeEach(func() { appName = random_name.CATSRandomName("APP") Eventually(cf.Cf( "push", appName, "--no-start", // app is defined by cloudfoundry-incubator/diego-dockerfiles
Expect(cf.Cf( "push", appName, "--no-start", "-b", Config.GetRubyBuildpackName(), "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().Dora, "-d", Config.GetAppsDomain(), "-c", "FOO=foo bundle exec rackup config.ru -p $PORT", ).Wait(Config.DefaultTimeoutDuration())).To(Exit(0)) app_helpers.SetBackend(appName) Expect(cf.Cf("start", appName).Wait(Config.CfPushTimeoutDuration())).To(Exit(0)) }) It("takes effect after a restart, not requiring a push", func() { Eventually(func() string { return helpers.CurlApp(Config, appName, "/env/FOO") }, Config.DefaultTimeoutDuration()).Should(ContainSubstring("foo")) guid := cf.Cf("app", appName, "--guid").Wait(Config.DefaultTimeoutDuration()).Out.Contents() appGuid := strings.TrimSpace(string(guid)) workflowhelpers.ApiRequest( "PUT", "/v2/apps/"+appGuid, nil, Config.DefaultTimeoutDuration(), `{"command":"FOO=bar bundle exec rackup config.ru -p $PORT"}`, ) Expect(cf.Cf("stop", appName).Wait(Config.DefaultTimeoutDuration())).To(Exit(0))
BeforeEach(func() { appName = pushApp() authToken = fetchOAuthToken() }) It("succeeds in sending all log lines", func(done Done) { msgChan := make(chan *events.LogMessage) errorChan := make(chan error, 5) connection := noaa.NewConsumer(getDopplerEndpoint(), &tls.Config{InsecureSkipVerify: config.SkipSSLValidation}, nil) defer connection.Close() appGuid := getAppGuid(appName) go connection.TailingLogs(appGuid, authToken, msgChan, errorChan) // Make app log some logs helpers.CurlApp(appName, "/loglines/5/LogStreamTestMarker") // Expect all logs to appear in Noaa consumer messages := waitForLogMessages(5, msgChan, errorChan) Expect(messages).To(HaveLen(5)) for _, message := range messages { Expect(message.GetAppId()).To(Equal(appGuid)) Expect(string(message.GetMessage())).To(ContainSubstring("LogStreamTestMarker")) } Consistently(errorChan).ShouldNot(Receive()) close(done) }, 120) })
. "github.com/onsi/gomega/gexec" "github.com/cloudfoundry-incubator/cf-test-helpers/cf" "github.com/cloudfoundry-incubator/cf-test-helpers/helpers" ) var _ = Describe("An application printing a bunch of output", func() { BeforeEach(func() { Eventually(pushNora(appName), CF_PUSH_TIMEOUT).Should(Succeed()) enableDiego(appName) Eventually(runCf("start", appName), CF_PUSH_TIMEOUT).Should(Succeed()) }) AfterEach(func() { Eventually(cf.Cf("logs", appName, "--recent")).Should(Exit()) Eventually(cf.Cf("delete", appName, "-f")).Should(Exit(0)) }) It("doesn't die when printing 32MB", func() { beforeId := helpers.CurlApp(appName, "/id") Expect(helpers.CurlAppWithTimeout(appName, "/logspew/32000", DEFAULT_TIMEOUT)). To(ContainSubstring("Just wrote 32000 kbytes to the log")) Consistently(func() string { return helpers.CurlApp(appName, "/id") }, "10s").Should(Equal(beforeId)) }) })
BeforeEach(func() { logs = cf.Cf("logs", appName) }) AfterEach(func() { // logs might be nil if the BeforeEach panics if logs != nil { logs.Interrupt().Wait(DEFAULT_TIMEOUT) } }) It("exercises basic loggregator behavior", func() { Eventually(logs, (DEFAULT_TIMEOUT + time.Minute)).Should(Say("Connected, tailing logs for app")) Eventually(func() string { return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond)) }, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha")) Eventually(logs, (DEFAULT_TIMEOUT + time.Minute)).Should(Say("Muahaha")) }) }) Context("cf logs --recent", func() { It("makes loggregator buffer and dump log messages", func() { Eventually(func() string { return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond)) }, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha")) Eventually(func() *Session { appLogsSession := cf.Cf("logs", "--recent", appName) Expect(appLogsSession.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
// Currently cannot work with multiple instances since CF always checks instance 0 files := cf.Cf("files", appName).Wait(DEFAULT_TIMEOUT) Expect(files).To(Exit(0)) Expect(files).To(Say("app/")) files = cf.Cf("files", appName, "app/").Wait(DEFAULT_TIMEOUT) Expect(files).To(Exit(0)) Expect(files).To(Say("config.ru")) files = cf.Cf("files", appName, "app/config.ru").Wait(DEFAULT_TIMEOUT) Expect(files).To(Exit(0)) Expect(files).To(Say("run Dora")) }) It("can show crash events", func() { helpers.CurlApp(appName, "/sigterm/KILL") Eventually(func() string { return string(cf.Cf("events", appName).Wait(DEFAULT_TIMEOUT).Out.Contents()) }, DEFAULT_TIMEOUT).Should(ContainSubstring("exited")) }) Context("with multiple instances", func() { BeforeEach(func() { Expect(cf.Cf("scale", appName, "-i", "2").Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) }) It("can be queried for state by instance", func() { app := cf.Cf("app", appName).Wait(DEFAULT_TIMEOUT) Expect(app).To(Exit(0)) Expect(app).To(Say("#0"))
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" "github.com/cloudfoundry-incubator/cf-test-helpers/cf" "github.com/cloudfoundry-incubator/cf-test-helpers/helpers" "github.com/cloudfoundry/cf-acceptance-tests/helpers/app_helpers" "github.com/cloudfoundry/cf-acceptance-tests/helpers/assets" "github.com/cloudfoundry/cf-acceptance-tests/helpers/random_name" ) var _ = AppsDescribe("Large_payload", func() { var appName string AfterEach(func() { app_helpers.AppReport(appName, Config.DefaultTimeoutDuration()) Expect(cf.Cf("delete", appName, "-f", "-r").Wait(Config.CfPushTimeoutDuration())).To(Exit(0)) }) It("should be able to curl for a large response body", func() { appName = random_name.CATSRandomName("APP") Expect(cf.Cf("push", appName, "--no-start", "-b", Config.GetRubyBuildpackName(), "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().Dora, "-d", Config.GetAppsDomain()).Wait(Config.DefaultTimeoutDuration())).To(Exit(0)) app_helpers.SetBackend(appName) Expect(cf.Cf("start", appName).Wait(Config.CfPushTimeoutDuration())).To(Exit(0)) Eventually(func() int { curlResponse := helpers.CurlApp(Config, appName, fmt.Sprintf("/largetext/5")) return len(curlResponse) }, 10*time.Second, 10*time.Second).Should(Equal(5 * 1024)) }) })
Expect(cf.Cf( "push", appName, "--no-start", "-b", config.RubyBuildpackName, "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().Dora, "-d", config.AppsDomain, ).Wait(DEFAULT_TIMEOUT)).To(Exit(0)) app_helpers.SetBackend(appName) Expect(cf.Cf("start", appName).Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) }) It("shows crash events", func() { helpers.CurlApp(appName, "/sigterm/KILL") Eventually(func() string { return string(cf.Cf("events", appName).Wait(DEFAULT_TIMEOUT).Out.Contents()) }, DEFAULT_TIMEOUT).Should(MatchRegexp("[eE]xited")) }) It("recovers", func() { id := helpers.CurlApp(appName, "/id") helpers.CurlApp(appName, "/sigterm/KILL") Eventually(func() string { return helpers.CurlApp(appName, "/id") }, DEFAULT_TIMEOUT).Should(Not(Equal(id))) }) })
var routeResponseJSON struct { Metadata struct { Guid string `json:"guid"` } `json:"metadata"` } json.Unmarshal([]byte(routePostResponseBody), &routeResponseJSON) routeGuid := routeResponseJSON.Metadata.Guid Expect(cf.Cf("curl", "/v2/apps/"+strings.TrimSpace(string(appGuid))+"/routes/"+string(routeGuid), "-X", "PUT").Wait(CF_PUSH_TIMEOUT)).To(Exit(0)) Eventually(func() string { return helpers.CurlAppRoot(appName) }, DEFAULT_TIMEOUT).Should(ContainSubstring("Hi, I'm Dora!")) Eventually(func() string { return helpers.CurlApp(appName, path) }, DEFAULT_TIMEOUT).Should(ContainSubstring("Hello, world!")) }) }) It("makes system environment variables available", func() { var envOutput string Eventually(func() string { envOutput = helpers.CurlApp(appName, "/env") return envOutput }, DEFAULT_TIMEOUT).Should(ContainSubstring(`"CF_INSTANCE_INDEX"=>"0"`)) Expect(envOutput).To(MatchRegexp(`"CF_INSTANCE_IP"=>"[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"`)) Expect(envOutput).To(MatchRegexp(`"CF_INSTANCE_PORT"=>"[0-9]+"`)) Expect(envOutput).To(MatchRegexp(`"CF_INSTANCE_ADDR"=>"[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+"`)) Expect(envOutput).To(MatchRegexp(`"CF_INSTANCE_PORTS"=>"\[(\{\\"external\\":[0-9]+,\\"internal\\":[0-9]+\},?)+\]"`)) })
BeforeEach(func() { appName = generator.RandomName() Eventually(cf.Cf( "push", appName, "-p", assets.NewAssets().Dora, "--no-start", "-b", "ruby_buildpack", "-i", "2"), CF_PUSH_TIMEOUT, ).Should(Exit(0)) enableSSH(appName) Eventually(cf.Cf("start", appName), CF_PUSH_TIMEOUT).Should(Exit(0)) Eventually(func() string { return helpers.CurlApp(appName, "/env/INSTANCE_INDEX") }).Should(Equal("1")) }) AfterEach(func() { Eventually(cf.Cf("logs", appName, "--recent")).Should(Exit()) Eventually(cf.Cf("delete", appName, "-f")).Should(Exit(0)) }) Describe("ssh", func() { It("can execute a remote command in the container", func() { envCmd := cf.Cf("ssh", "-i", "1", appName, "-c", "/usr/bin/env") Expect(envCmd.Wait()).To(Exit(0)) output := string(envCmd.Buffer().Contents())