blob: 35679b728c3ee9ce155bb477014c1277a754f613 [file] [log] [blame]
Jamie Hannaford8ed4fe72014-11-20 12:01:28 +01001// +build acceptance common
Ash Wilson15e0f272014-10-21 15:33:02 -04002
Samuel A. Falvo II43d83532014-07-31 14:34:48 -07003package tools
4
5import (
6 "crypto/rand"
Ash Wilsonfd566482014-09-23 15:47:35 -04007 "errors"
Jamie Hannaford930df422014-11-24 14:39:08 +01008 mrand "math/rand"
Ash Wilsona6ddde72014-10-22 15:26:42 -04009 "os"
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070010 "time"
Ash Wilsona6ddde72014-10-22 15:26:42 -040011
12 "github.com/rackspace/gophercloud"
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070013)
14
Ash Wilsonfd566482014-09-23 15:47:35 -040015// ErrTimeout is returned if WaitFor takes longer than 300 second to happen.
16var ErrTimeout = errors.New("Timed out")
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070017
Ash Wilsona6ddde72014-10-22 15:26:42 -040018// OnlyRS overrides the default Gophercloud behavior of using OS_-prefixed environment variables
19// if RS_ variables aren't present. Otherwise, they'll stomp over each other here in the acceptance
20// tests, where you need to have both defined.
21func OnlyRS(original gophercloud.AuthOptions) gophercloud.AuthOptions {
22 if os.Getenv("RS_AUTH_URL") == "" {
23 original.IdentityEndpoint = ""
24 }
25 if os.Getenv("RS_USERNAME") == "" {
26 original.Username = ""
27 }
28 if os.Getenv("RS_PASSWORD") == "" {
29 original.Password = ""
30 }
31 if os.Getenv("RS_API_KEY") == "" {
32 original.APIKey = ""
33 }
34 return original
35}
36
Ash Wilsonfd566482014-09-23 15:47:35 -040037// WaitFor polls a predicate function once per second to wait for a certain state to arrive.
38func WaitFor(predicate func() (bool, error)) error {
39 for i := 0; i < 300; i++ {
40 time.Sleep(1 * time.Second)
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070041
Ash Wilsonfd566482014-09-23 15:47:35 -040042 satisfied, err := predicate()
43 if err != nil {
44 return err
45 }
46 if satisfied {
47 return nil
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070048 }
49 }
Ash Wilsonfd566482014-09-23 15:47:35 -040050 return ErrTimeout
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070051}
52
Ash Wilsonfd566482014-09-23 15:47:35 -040053// MakeNewPassword generates a new string that's guaranteed to be different than the given one.
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070054func MakeNewPassword(oldPass string) string {
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070055 randomPassword := RandomString("", 16)
56 for randomPassword == oldPass {
57 randomPassword = RandomString("", 16)
58 }
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070059 return randomPassword
60}
61
Ash Wilsonfd566482014-09-23 15:47:35 -040062// RandomString generates a string of given length, but random content.
Samuel A. Falvo II43d83532014-07-31 14:34:48 -070063// All content will be within the ASCII graphic character set.
64// (Implementation from Even Shaw's contribution on
65// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
66func RandomString(prefix string, n int) string {
67 const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
68 var bytes = make([]byte, n)
69 rand.Read(bytes)
70 for i, b := range bytes {
71 bytes[i] = alphanum[b%byte(len(alphanum))]
72 }
73 return prefix + string(bytes)
74}
Ash Wilson20b4e872014-10-22 17:39:21 -040075
Jamie Hannaford930df422014-11-24 14:39:08 +010076// RandomInt will return a random integer between a specified range.
77func RandomInt(min, max int) int {
78 mrand.Seed(time.Now().Unix())
79 return mrand.Intn(max-min) + min
80}
81
Ash Wilson20b4e872014-10-22 17:39:21 -040082// Elide returns the first bit of its input string with a suffix of "..." if it's longer than
83// a comfortable 40 characters.
84func Elide(value string) string {
85 if len(value) > 40 {
86 return value[0:37] + "..."
87 }
88 return value
89}