// Login executes `deis auth:login` as the specified user. In the process, it creates the a // corresponding profile that contains the user's authentication token. Re-use of this profile is // for most other actions is what permits multiple test users to act in parallel without impacting // one another. func Login(user model.User) { sess, err := cmd.Start("deis auth:login %s --username=%s --password=%s", &user, settings.DeisControllerURL, user.Username, user.Password) Expect(err).To(BeNil()) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say(fmt.Sprintf("Logged in as %s\n", user.Username))) }
func listProcs(user model.User, app model.App) *Session { sess, err := cmd.Start("deis ps:list --app=%s", &user, app.Name) Eventually(sess).Should(Say("=== %s Processes", app.Name)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) return sess }
// Logout executes `deis auth:logout` as the specified user. func Logout(user model.User) { sess, err := cmd.Start("deis auth:logout", &user) Expect(err).To(BeNil()) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say("Logged out\n")) }
// Info executes `deis certs:info` as the specified user to retrieve information about the // specified cert. func Info(user model.User, cert model.Cert) *Session { sess, err := cmd.Start("deis certs:info %s", &user, cert.Name) Eventually(sess).Should(Say("=== %s Certificate", cert.Name)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) return sess }
func createOrPull(user model.User, app model.App, command string) { sess, err := cmd.Start("deis %s --app=%s %s", &user, command, app.Name, ExampleImage) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say("Creating build...")) Eventually(sess, settings.MaxEventuallyTimeout).Should(Exit(0)) time.Sleep(10 * time.Second) }
// Cancel executes `deis auth:cancel` as the specified user. func Cancel(user model.User) { sess, err := cmd.Start("deis auth:cancel --username=%s --password=%s --yes", &user, user.Username, user.Password) Expect(err).To(BeNil()) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say("Account cancelled\n")) }
// Remove executes `deis certs:remove` as the specified user to remove the specified cert. func Remove(user model.User, cert model.Cert) { sess, err := cmd.Start("deis certs:remove %s", &user, cert.Name) Eventually(sess).Should(Say("Removing %s...", cert.Name)) Eventually(sess).Should(Say("done")) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) Eventually(List(user).Wait().Out.Contents()).ShouldNot(ContainSubstring(cert.Name)) }
// Add executes `deis certs:add` as the specified user to add the specified cert. func Add(user model.User, cert model.Cert) { sess, err := cmd.Start("deis certs:add %s %s %s", &user, cert.Name, cert.CertPath, cert.KeyPath) Eventually(sess).Should(Say("Adding SSL endpoint...")) Eventually(sess, settings.MaxEventuallyTimeout).Should(Say("done")) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) Eventually(List(user).Wait().Out.Contents()).Should(ContainSubstring(cert.Name)) }
// Set executes `deis config:set` on the specified app as the specified user. func Set(user model.User, app model.App, key string, value string) *Session { sess, err := cmd.Start("deis config:set %s=%s --app=%s", &user, key, value, app.Name) Expect(err).NotTo(HaveOccurred()) sess.Wait(settings.MaxEventuallyTimeout) Eventually(sess).Should(Say("Creating config...")) Eventually(sess).Should(Exit(0)) return sess }
// Push executes a `git push deis master` from the current directory using the provided key. func Push(user model.User, keyPath string) { sess, err := cmd.Start("GIT_SSH=%s GIT_KEY=%s git push deis master", &user, settings.GitSSH, keyPath) Expect(err).NotTo(HaveOccurred()) // sess.Wait(settings.MaxEventuallyTimeout) // output := string(sess.Out.Contents()) // Expect(output).To(MatchRegexp(`Done, %s:v\d deployed to Deis`, app.Name)) Eventually(sess, settings.MaxEventuallyTimeout).Should(Exit(0)) }
// CancelAdmin deletes the admin user that was created to facilitate the tests. func CancelAdmin() { admin := model.Admin sess, err := cmd.Start("deis auth:cancel --username=%s --password=%s --yes", &admin, admin.Username, admin.Password) Expect(err).To(BeNil()) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say("Account cancelled\n")) }
// Detatch executes `deis certs:detach` as the specified user to detach the specified cert from // the specified domain. func Detach(user model.User, cert model.Cert, domain string) { sess, err := cmd.Start("deis certs:detach %s %s", &user, cert.Name, domain) // Explicitly build literal substring since 'domain' may be a wildcard domain ('*.foo.com') and // we don't want Gomega interpreting this string as a regexp Eventually(sess.Wait().Out.Contents()).Should(ContainSubstring(fmt.Sprintf("Detaching certificate %s from domain %s...", cert.Name, domain))) Eventually(sess, settings.MaxEventuallyTimeout).Should(Say("done")) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }
// Add executes `deis keys:add` as the specified user to add a new key to that user's account. func Add(user model.User) (string, string) { keyName, keyPath := createKey() sess, err := cmd.Start("deis keys:add %s.pub", &user, keyPath) Eventually(sess, settings.MaxEventuallyTimeout).Should(Say("Uploading %s.pub to deis... done", keyName)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) time.Sleep(5 * time.Second) // Wait for the key to propagate before continuing return keyName, keyPath }
// Register executes `deis auth:register` using a randomized username and returns a model.User. func Register() model.User { user := model.NewUser() sess, err := cmd.Start("deis auth:register %s --username=%s --password=%s --email=%s", &user, settings.DeisControllerURL, user.Username, user.Password, user.Email) Expect(err).To(BeNil()) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say(fmt.Sprintf("Logged in as %s\n", user.Username))) return user }
// Remove executes `deis domains:remove` as the specified user to remove the specified domain from // the specified app. func Remove(user model.User, app model.App, domain string) { sess, err := cmd.Start("deis domains:remove %s --app=%s", &user, domain, app.Name) // Explicitly build literal substring since 'domain' may be a wildcard domain ('*.foo.com') and // we don't want Gomega interpreting this string as a regexp Eventually(sess.Wait().Out.Contents()).Should(ContainSubstring(fmt.Sprintf("Removing %s from %s...", domain, app.Name))) Eventually(sess, settings.MaxEventuallyTimeout).Should(Say("done")) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }
// Destroy executes `deis apps:destroy` on the specified app as the specified user. func Destroy(user model.User, app model.App) *Session { sess, err := cmd.Start("deis apps:destroy --app=%s --confirm=%s", &user, app.Name, app.Name) Expect(err).NotTo(HaveOccurred()) sess.Wait(settings.MaxEventuallyTimeout) Eventually(sess).Should(Say("Destroying %s...", app.Name)) Eventually(sess).Should(Say(`done in `)) Eventually(sess).Should(Exit(0)) return sess }
// RegisterAdmin executes `deis auth:register`, using hard-coded username, password, and email // address. When this is executed, it is executed in hopes of registering Workflow's FIRST user, // which will automatically have admin permissions. If this should fail, the function proceeds // with logging in using those same hard-coded credentials, in the hopes that the reason for the // failure is that such an account already exists, having been created by a previous execution of // the tests. func RegisterAdmin() { admin := model.Admin sess, err := cmd.Start("deis auth:register %s --username=%s --password=%s --email=%s", &admin, settings.DeisControllerURL, admin.Username, admin.Password, admin.Email) Expect(err).To(BeNil()) Eventually(sess).Should(Exit()) Expect(err).NotTo(HaveOccurred()) // We cannot entirely count on the registration having succeeded. It may have failed if a user // with the username "admin" already exists. However, if that user IS indeed an admin and their // password is also "admin" (e.g. the admin was created by a previous run of these tests), then // we can proceed... so attempt to login... Login(admin) // Now verify this user is an admin by running a privileged command. sess, err = cmd.Start("deis users:list", &admin) Expect(err).To(BeNil()) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) }
func listDeploymentProcs(user model.User, app model.App, proctype string) *Session { sess, err := cmd.Start("deis ps:list --app=%s", &user, app.Name) Eventually(sess).Should(Say("=== %s Processes", app.Name)) if proctype != "" { Eventually(sess).Should(Say("--- %s:", proctype)) } Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) return sess }
// Create executes `deis apps:create` as the specified user with the specified, arvitrary options. func Create(user model.User, options ...string) model.App { noRemote := false app := model.NewApp() sess, err := cmd.Start("deis apps:create %s %s", &user, app.Name, strings.Join(options, " ")) Expect(err).NotTo(HaveOccurred()) sess.Wait(settings.MaxEventuallyTimeout) Eventually(sess).Should(Say("created %s", app.Name)) for _, option := range options { if option == "--no-remote" { noRemote = true break } } if !noRemote { Eventually(sess).Should(Say("Git remote deis added")) } Eventually(sess).Should(Say("remote available at ")) Eventually(sess).Should(Exit(0)) return app }
}) Context("who owns an existing app", func() { var app model.App BeforeEach(func() { app = apps.Create(user, "--no-remote") }) AfterEach(func() { apps.Destroy(user, app) }) Specify("that user can list that app's registry information", func() { sess, err := cmd.Start("deis registry:list --app=%s", &user, app.Name) Eventually(sess).Should(Say("=== %s Registry", app.Name)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }) Specify("that user cannot unset an invalid registry information", func() { sess, err := cmd.Start("deis registry:unset --app=%s munkafolyamat", &user, app.Name) Eventually(sess).ShouldNot(Say(`munkafolyamat\s+yeah`, app.Name)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(1)) }) Specify("that user can set a valid registry information", func() { // Setting a port first is required for a private registry sess, err := cmd.Start("deis config:set -a %s PORT=5000", &user, app.Name)
// Regenerate executes `deis auth:regenerate` as the specified user. func Regenerate(user model.User) { sess, err := cmd.Start("deis auth:regenerate", &user) Eventually(sess).Should(Say("Token Regenerated")) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) }
// Whoami executes `deis auth:whoami` as the specified user. func Whoami(user model.User) { sess, err := cmd.Start("deis auth:whoami", &user) Eventually(sess).Should(Say("You are %s", user.Username)) Eventually(sess).Should(Exit(0)) Expect(err).NotTo(HaveOccurred()) }
"github.com/deis/workflow-e2e/tests/util" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gbytes" . "github.com/onsi/gomega/gexec" ) var _ = Describe("deis users", func() { Context("with an existing admin", func() { admin := model.Admin Specify("that admin can list all users", func() { sess, err := cmd.Start("deis users:list", &admin) Eventually(sess).Should(Say("=== Users")) output := string(sess.Out.Contents()) Expect(output).To(ContainSubstring(admin.Username)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }) }) Context("with an existing non-admin user", func() { var user model.User BeforeEach(func() { user = auth.Register()
Context("who owns an existing app that has already been deployed", func() { var app model.App BeforeEach(func() { app = apps.Create(user, "--no-remote") builds.Create(user, app) }) AfterEach(func() { apps.Destroy(user, app) }) Specify("that user can list environment variables on that app", func() { sess, err := cmd.Start("deis config:list -a %s", &user, app.Name) Eventually(sess).Should(Say("=== %s Config", app.Name)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }) Specify("that user can set environment variables on that app", func() { sess, err := cmd.Start("deis config:set -a %s POWERED_BY=midi-chlorians", &user, app.Name) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say("Creating config")) Eventually(sess, settings.MaxEventuallyTimeout).Should(Say("=== %s Config", app.Name)) Eventually(sess).Should(Say(`POWERED_BY\s+midi-chlorians`)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) sess, err = cmd.Start("deis config:list -a %s", &user, app.Name)
user = auth.Register() }) AfterEach(func() { auth.Cancel(user) }) Specify("that user can create an app without a git remote", func() { app := apps.Create(user, "--no-remote") apps.Destroy(user, app) }) Specify("that user can create an app that uses a custom buildpack", func() { app := apps.Create(user, "--no-remote", "--buildpack https://weird-buildpacks.io/lisp") defer apps.Destroy(user, app) sess, err := cmd.Start("deis config:list -a %s", &user, app.Name) Eventually(sess).Should(Say("BUILDPACK_URL")) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }) Context("and an app that does not exist", func() { bogusAppName := "bogus-app-name" Specify("that user cannot get information about that app", func() { sess, err := cmd.Start("deis info -a %s", &user, bogusAppName) Eventually(sess.Err).Should(Say("Not found.")) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(1)) })
// Delete executes `deis perms:delete` as the specified user to revoke permissions on the specified // app from a second user. func Delete(user model.User, app model.App, revokeUser model.User) { sess, err := cmd.Start("deis perms:delete %s --app=%s", &user, revokeUser.Username, app.Name) Eventually(sess, settings.MaxEventuallyTimeout).Should(Say("Removing %s from %s collaborators... done", revokeUser.Username, app.Name)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }
Eventually(sess2).Should(Exit(128)) git.PushUntilResult(user, keyPath, model.CmdResult{ Out: nil, Err: []byte("Everything up-to-date"), ExitCode: 0, }) Eventually(sess, settings.MaxEventuallyTimeout).Should(Exit(0)) git.Curl(app, "Powered by Deis") }) Context("with a bad buildpack", func() { BeforeEach(func() { badBuildpackURL := "https://github.com/deis/heroku-buildpack-epic-fail.git" sess, err := cmd.Start("deis config:set BUILDPACK_URL=%s", &user, badBuildpackURL) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Say("BUILDPACK_URL")) Eventually(sess).Should(Exit(0)) }) AfterEach(func() { sess, err := cmd.Start("deis config:unset BUILDPACK_URL", &user) Expect(err).NotTo(HaveOccurred()) Eventually(sess).ShouldNot(Say("BUILDPACK_URL")) Eventually(sess).Should(Exit(0)) }) Specify("that user can't deploy the app", func() { sess := git.StartPush(user, keyPath) Eventually(sess.Err, settings.MaxEventuallyTimeout).Should(Say("-----> Fetching custom buildpack"))
}) Context("with an existing user", func() { var user model.User BeforeEach(func() { user = auth.Register() }) AfterEach(func() { auth.Cancel(user) }) Specify("that user cannot add a cert with a malformed name", func() { sess, err := cmd.Start("deis certs:add %s %s %s", &user, "bogus.cert.name", cert.CertPath, cert.KeyPath) // TODO: Figure out spacing issues that necessitate this workaround. output := sess.Wait().Err.Contents() Expect(strings.TrimSpace(string(output))).To(Equal(util.PrependError(deis.ErrInvalidName))) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(1)) }) Specify("that user cannot add a cert using a non-existent cert file", func() { nonExistentCertFile := "non.existent.cert" sess, err := cmd.Start("deis certs:add %s %s %s", &user, cert.Name, nonExistentCertFile, cert.KeyPath) Eventually(sess.Err).Should(Say("open %s: no such file or directory", nonExistentCertFile)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(1)) })
"github.com/deis/workflow-e2e/tests/settings" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gbytes" . "github.com/onsi/gomega/gexec" ) var _ = Describe("deis perms", func() { Context("with an existing admin", func() { admin := model.Admin Specify("that admin can list admins", func() { sess, err := cmd.Start("deis perms:list --admin", &admin) Eventually(sess).Should(Say("=== Administrators")) Eventually(sess).Should(Say(admin.Username)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) }) Context("and another existing user", func() { var otherUser model.User BeforeEach(func() { otherUser = auth.Register() }) AfterEach(func() {
Context("who owns an existing app that has already been deployed", func() { var app model.App BeforeEach(func() { app = apps.Create(user, "--no-remote") builds.Create(user, app) }) AfterEach(func() { apps.Destroy(user, app) }) DescribeTable("that user can scale that app up and down", func(scaleTo, respCode int) { sess, err := cmd.Start("deis ps:scale cmd=%d --app=%s", &user, scaleTo, app.Name) Eventually(sess).Should(Say("Scaling processes... but first,")) Eventually(sess, settings.MaxEventuallyTimeout).Should(Say(`done in \d+s`)) Eventually(sess).Should(Say("=== %s Processes", app.Name)) Expect(err).NotTo(HaveOccurred()) Eventually(sess).Should(Exit(0)) // test that there are the right number of processes listed procsListing := listProcs(user, app).Out.Contents() procs := scrapeProcs(app.Name, procsListing) Expect(len(procs)).To(Equal(scaleTo)) // curl the app's root URL and print just the HTTP response code cmdRetryTimeout := 60 curlCmd := model.Cmd{CommandLineString: fmt.Sprintf(`curl -sL -w "%%{http_code}\\n" "%s" -o /dev/null`, app.URL)} Eventually(cmd.Retry(curlCmd, strconv.Itoa(respCode), cmdRetryTimeout)).Should(BeTrue())