10671: Merge branch 'master' into 10671-pipeline-instance-finish-time
[arvados.git] / sdk / go / arvadostest / run_servers.go
1 package arvadostest
2
3 import (
4         "bufio"
5         "bytes"
6         "fmt"
7         "io/ioutil"
8         "log"
9         "os"
10         "os/exec"
11         "path"
12         "strconv"
13         "strings"
14 )
15
16 var authSettings = make(map[string]string)
17
18 // ResetEnv resets test env
19 func ResetEnv() {
20         for k, v := range authSettings {
21                 os.Setenv(k, v)
22         }
23 }
24
25 // APIHost returns the address:port of the current test server.
26 func APIHost() string {
27         h := authSettings["ARVADOS_API_HOST"]
28         if h == "" {
29                 log.Fatal("arvadostest.APIHost() was called but authSettings is not populated")
30         }
31         return h
32 }
33
34 // ParseAuthSettings parses auth settings from given input
35 func ParseAuthSettings(authScript []byte) {
36         scanner := bufio.NewScanner(bytes.NewReader(authScript))
37         for scanner.Scan() {
38                 line := scanner.Text()
39                 if 0 != strings.Index(line, "export ") {
40                         log.Printf("Ignoring: %v", line)
41                         continue
42                 }
43                 toks := strings.SplitN(strings.Replace(line, "export ", "", 1), "=", 2)
44                 if len(toks) == 2 {
45                         authSettings[toks[0]] = toks[1]
46                 } else {
47                         log.Fatalf("Could not parse: %v", line)
48                 }
49         }
50         log.Printf("authSettings: %v", authSettings)
51 }
52
53 var pythonTestDir string
54
55 func chdirToPythonTests() {
56         if pythonTestDir != "" {
57                 if err := os.Chdir(pythonTestDir); err != nil {
58                         log.Fatalf("chdir %s: %s", pythonTestDir, err)
59                 }
60                 return
61         }
62         for {
63                 if err := os.Chdir("sdk/python/tests"); err == nil {
64                         pythonTestDir, err = os.Getwd()
65                         return
66                 }
67                 if parent, err := os.Getwd(); err != nil || parent == "/" {
68                         log.Fatalf("sdk/python/tests/ not found in any ancestor")
69                 }
70                 if err := os.Chdir(".."); err != nil {
71                         log.Fatal(err)
72                 }
73         }
74 }
75
76 // StartAPI starts test API server
77 func StartAPI() {
78         cwd, _ := os.Getwd()
79         defer os.Chdir(cwd)
80         chdirToPythonTests()
81
82         cmd := exec.Command("python", "run_test_server.py", "start", "--auth", "admin")
83         cmd.Stdin = nil
84         cmd.Stderr = os.Stderr
85
86         authScript, err := cmd.Output()
87         if err != nil {
88                 log.Fatalf("%+v: %s", cmd.Args, err)
89         }
90         ParseAuthSettings(authScript)
91         ResetEnv()
92 }
93
94 // StopAPI stops test API server
95 func StopAPI() {
96         cwd, _ := os.Getwd()
97         defer os.Chdir(cwd)
98         chdirToPythonTests()
99
100         bgRun(exec.Command("python", "run_test_server.py", "stop"))
101 }
102
103 // StartKeep starts the given number of keep servers,
104 // optionally with -enforce-permissions enabled.
105 // Use numKeepServers = 2 and enforcePermissions = false under all normal circumstances.
106 func StartKeep(numKeepServers int, enforcePermissions bool) {
107         cwd, _ := os.Getwd()
108         defer os.Chdir(cwd)
109         chdirToPythonTests()
110
111         cmdArgs := []string{"run_test_server.py", "start_keep", "--num-keep-servers", strconv.Itoa(numKeepServers)}
112         if enforcePermissions {
113                 cmdArgs = append(cmdArgs, "--keep-enforce-permissions")
114         }
115
116         bgRun(exec.Command("python", cmdArgs...))
117 }
118
119 // StopKeep stops keep servers that were started with StartKeep.
120 // numkeepServers should be the same value that was passed to StartKeep,
121 // which is 2 under all normal circumstances.
122 func StopKeep(numKeepServers int) {
123         cwd, _ := os.Getwd()
124         defer os.Chdir(cwd)
125         chdirToPythonTests()
126
127         cmd := exec.Command("python", "run_test_server.py", "stop_keep", "--num-keep-servers", strconv.Itoa(numKeepServers))
128         cmd.Stdin = nil
129         cmd.Stderr = os.Stderr
130         cmd.Stdout = os.Stderr
131         if err := cmd.Run(); err != nil {
132                 log.Fatalf("%+v: %s", cmd.Args, err)
133         }
134 }
135
136 // Start cmd, with stderr and stdout redirected to our own
137 // stderr. Return when the process exits, but do not wait for its
138 // stderr and stdout to close: any grandchild processes will continue
139 // writing to our stderr.
140 func bgRun(cmd *exec.Cmd) {
141         cmd.Stdin = nil
142         cmd.Stderr = os.Stderr
143         cmd.Stdout = os.Stderr
144         if err := cmd.Start(); err != nil {
145                 log.Fatalf("%+v: %s", cmd.Args, err)
146         }
147         if _, err := cmd.Process.Wait(); err != nil {
148                 log.Fatalf("%+v: %s", cmd.Args, err)
149         }
150 }
151
152 // CreateBadPath creates a tmp dir, appends given string and returns that path
153 // This will guarantee that the path being returned does not exist
154 func CreateBadPath() (badpath string, err error) {
155         tempdir, err := ioutil.TempDir("", "bad")
156         if err != nil {
157                 return "", fmt.Errorf("Could not create temporary directory for bad path: %v", err)
158         }
159         badpath = path.Join(tempdir, "bad")
160         return badpath, nil
161 }
162
163 // DestroyBadPath deletes the tmp dir created by the previous CreateBadPath call
164 func DestroyBadPath(badpath string) error {
165         tempdir := path.Join(badpath, "..")
166         err := os.Remove(tempdir)
167         if err != nil {
168                 return fmt.Errorf("Could not remove bad path temporary directory %v: %v", tempdir, err)
169         }
170         return nil
171 }