appName = generator.RandomName()

		Expect(cf.Cf(
			"push", appName,
			"-p", helpers.NewAssets().Dora,
			"-d", helpers.LoadConfig().AppsDomain,
			"-c", "FOO=foo bundle exec rackup config.ru -p $PORT",
		).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
	})

	AfterEach(func() {
		Expect(cf.Cf("delete", appName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})

	It("takes effect after a restart, not requiring a push", func() {
		Expect(helpers.CurlApp(appName, "/env/FOO")).To(ContainSubstring("foo"))

		var response cf.QueryResponse

		cf.ApiRequest("GET", "/v2/apps?q=name:"+appName, &response)

		Expect(response.Resources).To(HaveLen(1))

		appGuid := response.Resources[0].Metadata.Guid

		cf.ApiRequest(
			"PUT",
			"/v2/apps/"+appGuid,
			nil,
			`{"command":"FOO=bar bundle exec rackup config.ru -p $PORT"}`,
		)
		// Currently cannot work with multiple instances since GCF 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"))
var _ = Describe("An application printing a bunch of output", func() {
	var appName string

	BeforeEach(func() {
		appName = generator.RandomName()

		Expect(cf.Cf("push", appName, "-p", helpers.NewAssets().Dora).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
	})

	AfterEach(func() {
		Expect(cf.Cf("delete", appName, "-f").Wait(DEFAULT_TIMEOUT)).Should(Exit(0))
	})

	It("doesn't die when printing 32MB", func() {
		beforeId := helpers.CurlApp(appName, "/id")

		Expect(helpers.CurlAppWithTimeout(appName, "/logspew/33554432", LONG_CURL_TIMEOUT)).To(ContainSubstring("Just wrote 33554432 random bytes 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))

		Expect(helpers.CurlApp(appName, "/logspew/2")).To(ContainSubstring("Just wrote 2 random bytes to the log"))
	})
})