github.com/mboersma/deis@v1.13.4/tests/apps_test.go (about) 1 // +build integration 2 3 package tests 4 5 import ( 6 "fmt" 7 "math/rand" 8 "os" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/deis/deis/tests/utils" 14 ) 15 16 var ( 17 appsCreateCmd = "apps:create {{.AppName}}" 18 appsCreateCmdNoRemote = "apps:create {{.AppName}} --no-remote" 19 appsCreateCmdBuildpack = "apps:create {{.AppName}} --buildpack https://example.com" 20 appsListCmd = "apps:list" 21 appsRunCmd = "apps:run echo Hello, 世界" 22 appsOpenCmd = "apps:open --app={{.AppName}}" 23 appsLogsCmd = "apps:logs --app={{.AppName}}" 24 appsLogsLimitCmd = "apps:logs --app={{.AppName}} -n 1" 25 appsInfoCmd = "apps:info --app={{.AppName}}" 26 appsDestroyCmd = "apps:destroy --app={{.AppName}} --confirm={{.AppName}}" 27 appsDestroyCmdNoApp = "apps:destroy --confirm={{.AppName}}" 28 appsTransferCmd = "apps:transfer {{.NewOwner}} --app={{.AppName}}" 29 ) 30 31 func randomString(n int) string { 32 // Be sure we've seeded the random number generator, otherwise we could get the same string 33 // every time. 34 rand.Seed(time.Now().UnixNano()) 35 var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 36 b := make([]rune, n) 37 for i := range b { 38 b[i] = letters[rand.Intn(len(letters))] 39 } 40 return string(b) 41 } 42 43 func TestApps(t *testing.T) { 44 params := appsSetup(t) 45 appsCreateTest(t, params) 46 appsListTest(t, params, false) 47 appsLogsTest(t, params) 48 appsInfoTest(t, params) 49 appsRunTest(t, params) 50 appsOpenTest(t, params) 51 appsDestroyTest(t, params) 52 appsListTest(t, params, true) 53 appsTransferTest(t, params) 54 } 55 56 func appsSetup(t *testing.T) *utils.DeisTestConfig { 57 cfg := utils.GetGlobalConfig() 58 cfg.AppName = "appssample" 59 utils.Execute(t, authLoginCmd, cfg, false, "") 60 utils.Execute(t, gitCloneCmd, cfg, false, "") 61 return cfg 62 } 63 64 func appsCreateTest(t *testing.T, params *utils.DeisTestConfig) { 65 wd, _ := os.Getwd() 66 defer os.Chdir(wd) 67 if err := utils.Chdir(params.ExampleApp); err != nil { 68 t.Fatal(err) 69 } 70 // TODO: move --buildpack to client unit tests 71 utils.Execute(t, appsCreateCmdBuildpack, params, false, "BUILDPACK_URL") 72 utils.Execute(t, appsDestroyCmdNoApp, params, false, "") 73 utils.Execute(t, appsCreateCmd, params, false, "") 74 utils.Execute(t, appsCreateCmd, params, true, "This field must be unique.") 75 } 76 77 func appsDestroyTest(t *testing.T, params *utils.DeisTestConfig) { 78 if err := utils.Chdir(params.ExampleApp); err != nil { 79 t.Fatal(err) 80 } 81 utils.Execute(t, appsDestroyCmd, params, false, "") 82 if err := utils.Chdir(".."); err != nil { 83 t.Fatal(err) 84 } 85 if err := utils.Rmdir(params.ExampleApp); err != nil { 86 t.Fatal(err) 87 } 88 } 89 90 func appsInfoTest(t *testing.T, params *utils.DeisTestConfig) { 91 utils.Execute(t, appsInfoCmd, params, false, "") 92 } 93 94 func appsListTest(t *testing.T, params *utils.DeisTestConfig, notflag bool) { 95 utils.CheckList(t, appsListCmd, params, params.AppName, notflag) 96 } 97 98 func appsLogsTest(t *testing.T, params *utils.DeisTestConfig) { 99 cmd := appsLogsCmd 100 // test for application lifecycle logs 101 utils.Execute(t, cmd, params, false, "204 NO CONTENT") 102 if err := utils.Chdir(params.ExampleApp); err != nil { 103 t.Fatal(err) 104 } 105 utils.Execute(t, gitPushCmd, params, false, "") 106 utils.CurlApp(t, *params) 107 utils.Execute(t, cmd, params, false, "created initial release") 108 utils.Execute(t, cmd, params, false, "listening on 5000...") 109 110 utils.Execute(t, appsLogsLimitCmd, params, false, "") 111 112 if err := utils.Chdir(".."); err != nil { 113 t.Fatal(err) 114 } 115 } 116 117 func appsOpenTest(t *testing.T, params *utils.DeisTestConfig) { 118 utils.CurlApp(t, *params) 119 utils.CurlWithFail(t, fmt.Sprintf("http://%s.%s", "this-app-does-not-exist", params.Domain), true, "404 Not Found") 120 } 121 122 func appsRunTest(t *testing.T, params *utils.DeisTestConfig) { 123 cmd := appsRunCmd 124 if err := utils.Chdir(params.ExampleApp); err != nil { 125 t.Fatal(err) 126 } 127 utils.CheckList(t, cmd, params, "Hello, 世界", false) 128 utils.Execute(t, "apps:run env", params, true, "GIT_SHA") 129 // Fleet/systemd unit files have a limit of 2048 characters per line or else one encounters 130 // problems parsing the unit. To verify long log messages are truncated and do not crash 131 // logspout (see https://github.com/deis/deis/issues/2046) we must issue a (relatively) short 132 // command via `deis apps:run` that produces a LONG, but testable (predictable) log message we 133 // can search for in the output of `deis logs`. 134 // 135 // The strategy for achieving this is to generate 1k random characters, then use that with a 136 // command submitted via `deis apps:run` that will echo those 1k bytes 64x (on a single line). 137 // Such a message is long enough to crash logspout if handled improperly and ALSO gives us a 138 // large, distinct, and predictable string we can search for in the logs to assert success (and 139 // assert that the message didn't crash logspout) WITHOUT ever needing to transmit such an 140 // egregiously long command via `deis apps:run`. 141 largeString := randomString(1024) 142 utils.Execute(t, fmt.Sprintf("apps:run \"printf '%s%%.0s' {1..64}\"", largeString), params, false, largeString) 143 // To assert the long message didn't crash logspout AND made it to the logger, we will search 144 // the logs for a fragment of the long message-- specifically 2x the random string we generated. 145 // This will help us ensure the actual log message made it through and not JUST the log message 146 // that states the command being execured via `deis apps:run`. We want to find the former, not 147 // the latter because the latter is too short a message to have possibly crashed logspout if 148 // mishandled. 149 utils.Execute(t, "logs", params, false, strings.Repeat(largeString, 2)) 150 if err := utils.Chdir(".."); err != nil { 151 t.Fatal(err) 152 } 153 utils.Execute(t, cmd, params, true, "Not found") 154 } 155 156 func appsTransferTest(t *testing.T, params *utils.DeisTestConfig) { 157 user := utils.GetGlobalConfig() 158 user.UserName, user.Password = "app-transfer-test", "test" 159 user.AppName = "transfer-test" 160 user.NewOwner = params.UserName 161 utils.Execute(t, authRegisterCmd, user, false, "") 162 utils.Execute(t, authLoginCmd, user, false, "") 163 utils.Execute(t, appsCreateCmdNoRemote, user, false, "") 164 utils.Execute(t, appsTransferCmd, user, false, "") 165 utils.Execute(t, appsInfoCmd, user, true, "403 FORBIDDEN") 166 utils.Execute(t, authLoginCmd, params, false, "") 167 params.AppName = user.AppName 168 utils.CheckList(t, appsInfoCmd, params, params.UserName, false) 169 }