Merge branch '20831-user-table-locks' refs #20831
[arvados.git] / sdk / go / arvadostest / run_servers.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package arvadostest
6
7 import (
8         "crypto/tls"
9         "fmt"
10         "io/ioutil"
11         "log"
12         "net/http"
13         "os"
14         "os/exec"
15         "path"
16         "strconv"
17         "strings"
18
19         "gopkg.in/check.v1"
20 )
21
22 var authSettings = make(map[string]string)
23
24 // ResetEnv resets ARVADOS_* env vars to whatever they were the first
25 // time this func was called.
26 //
27 // Call it from your SetUpTest or SetUpSuite func if your tests modify
28 // env vars.
29 func ResetEnv() {
30         if len(authSettings) == 0 {
31                 for _, e := range os.Environ() {
32                         e := strings.SplitN(e, "=", 2)
33                         if len(e) == 2 {
34                                 authSettings[e[0]] = e[1]
35                         }
36                 }
37         } else {
38                 for k, v := range authSettings {
39                         os.Setenv(k, v)
40                 }
41         }
42 }
43
44 var pythonTestDir string
45
46 func chdirToPythonTests() {
47         if pythonTestDir != "" {
48                 if err := os.Chdir(pythonTestDir); err != nil {
49                         log.Fatalf("chdir %s: %s", pythonTestDir, err)
50                 }
51                 return
52         }
53         for {
54                 if err := os.Chdir("sdk/python/tests"); err == nil {
55                         pythonTestDir, err = os.Getwd()
56                         if err != nil {
57                                 log.Fatal(err)
58                         }
59                         return
60                 }
61                 if parent, err := os.Getwd(); err != nil || parent == "/" {
62                         log.Fatalf("sdk/python/tests/ not found in any ancestor")
63                 }
64                 if err := os.Chdir(".."); err != nil {
65                         log.Fatal(err)
66                 }
67         }
68 }
69
70 func ResetDB(c *check.C) {
71         hc := http.Client{Transport: &http.Transport{
72                 TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
73         }}
74         req, err := http.NewRequest("POST", "https://"+os.Getenv("ARVADOS_TEST_API_HOST")+"/database/reset", nil)
75         c.Assert(err, check.IsNil)
76         req.Header.Set("Authorization", "Bearer "+AdminToken)
77         resp, err := hc.Do(req)
78         c.Assert(err, check.IsNil)
79         defer resp.Body.Close()
80         c.Check(resp.StatusCode, check.Equals, http.StatusOK)
81 }
82
83 // StartKeep starts the given number of keep servers,
84 // optionally with --keep-blob-signing enabled.
85 // Use numKeepServers = 2 and blobSigning = false under all normal circumstances.
86 func StartKeep(numKeepServers int, blobSigning bool) {
87         cwd, _ := os.Getwd()
88         defer os.Chdir(cwd)
89         chdirToPythonTests()
90
91         cmdArgs := []string{"run_test_server.py", "start_keep", "--num-keep-servers", strconv.Itoa(numKeepServers)}
92         if blobSigning {
93                 cmdArgs = append(cmdArgs, "--keep-blob-signing")
94         }
95
96         bgRun(exec.Command("python", cmdArgs...))
97 }
98
99 // StopKeep stops keep servers that were started with StartKeep.
100 // numkeepServers should be the same value that was passed to StartKeep,
101 // which is 2 under all normal circumstances.
102 func StopKeep(numKeepServers int) {
103         cwd, _ := os.Getwd()
104         defer os.Chdir(cwd)
105         chdirToPythonTests()
106
107         cmd := exec.Command("python", "run_test_server.py", "stop_keep", "--num-keep-servers", strconv.Itoa(numKeepServers))
108         bgRun(cmd)
109         // Without Wait, "go test" in go1.10.1 tends to hang. https://github.com/golang/go/issues/24050
110         cmd.Wait()
111 }
112
113 // Start cmd, with stderr and stdout redirected to our own
114 // stderr. Return when the process exits, but do not wait for its
115 // stderr and stdout to close: any grandchild processes will continue
116 // writing to our stderr.
117 func bgRun(cmd *exec.Cmd) {
118         cmd.Stdin = nil
119         cmd.Stderr = os.Stderr
120         cmd.Stdout = os.Stderr
121         if err := cmd.Start(); err != nil {
122                 log.Fatalf("%+v: %s", cmd.Args, err)
123         }
124         if _, err := cmd.Process.Wait(); err != nil {
125                 log.Fatalf("%+v: %s", cmd.Args, err)
126         }
127 }
128
129 // CreateBadPath creates a tmp dir, appends given string and returns that path
130 // This will guarantee that the path being returned does not exist
131 func CreateBadPath() (badpath string, err error) {
132         tempdir, err := ioutil.TempDir("", "bad")
133         if err != nil {
134                 return "", fmt.Errorf("Could not create temporary directory for bad path: %v", err)
135         }
136         badpath = path.Join(tempdir, "bad")
137         return badpath, nil
138 }
139
140 // DestroyBadPath deletes the tmp dir created by the previous CreateBadPath call
141 func DestroyBadPath(badpath string) error {
142         tempdir := path.Join(badpath, "..")
143         err := os.Remove(tempdir)
144         if err != nil {
145                 return fmt.Errorf("Could not remove bad path temporary directory %v: %v", tempdir, err)
146         }
147         return nil
148 }