11980: debian9 as a new target
[arvados-dev.git] / arvados-version-server / arvados-version-server_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package main
6
7 import (
8         "fmt"
9         . "gopkg.in/check.v1"
10         "io/ioutil"
11         "log"
12         "net/http"
13         "os"
14         "testing"
15         "time"
16 )
17
18 // Hook gocheck into the "go test" runner.
19 func Test(t *testing.T) { TestingT(t) }
20
21 // Gocheck boilerplate
22 var _ = Suite(&ServerRequiredSuite{})
23 var _ = Suite(&ServerNotRequiredSuite{})
24
25 type ServerRequiredSuite struct{}
26 type ServerNotRequiredSuite struct{}
27
28 var tmpConfigFileName string
29
30 func closeListener() {
31         if listener != nil {
32                 listener.Close()
33         }
34 }
35
36 func (s *ServerNotRequiredSuite) TestConfig(c *C) {
37         var config Config
38
39         // A specified but non-existing config path needs to result in an error
40         err := readConfig(&config, "/nosuchdir89j7879/8hjwr7ojgyy7", defaultConfigPath)
41         c.Assert(err, NotNil)
42
43         // No configuration file but default configuration path specified
44         // should result in the default config being used
45         err = readConfig(&config, "/nosuchdir89j7879/8hjwr7ojgyy7", "/nosuchdir89j7879/8hjwr7ojgyy7")
46         c.Assert(err, IsNil)
47
48         c.Check(config.DirPath, Equals, "")
49         c.Check(config.CacheDirPath, Equals, "")
50         c.Check(config.GitExecutablePath, Equals, "")
51         c.Check(config.ListenPort, Equals, "")
52
53         // Test parsing of config data
54         tmpfile, err := ioutil.TempFile(os.TempDir(), "config")
55         c.Check(err, IsNil)
56         defer os.Remove(tmpfile.Name())
57
58         argsS := `{"DirPath": "/x/y", "CacheDirPath": "/x/z", "GitExecutablePath": "/usr/local/bin/gitexecutable", "ListenPort": "12345"}`
59         _, err = tmpfile.Write([]byte(argsS))
60         c.Check(err, IsNil)
61
62         err = readConfig(&config, tmpfile.Name(), defaultConfigPath)
63         c.Assert(err, IsNil)
64
65         c.Check(config.DirPath, Equals, "/x/y")
66         c.Check(config.CacheDirPath, Equals, "/x/z")
67         c.Check(config.GitExecutablePath, Equals, "/usr/local/bin/gitexecutable")
68         c.Check(config.ListenPort, Equals, "12345")
69
70 }
71
72 func (s *ServerNotRequiredSuite) TestFlags(c *C) {
73
74         args := []string{"arvados-version-server"}
75         os.Args = append(args)
76         //go main()
77
78 }
79
80 func runServer(c *C) {
81         tmpfile, err := ioutil.TempFile(os.TempDir(), "config")
82         c.Check(err, IsNil)
83
84         tmpConfigFileName = tmpfile.Name()
85
86         argsS := `{"DirPath": "", "CacheDirPath": "", "GitExecutablePath": "", "ListenPort": "12345"}`
87         _, err = tmpfile.Write([]byte(argsS))
88         c.Check(err, IsNil)
89
90         args := []string{"arvados-version-server"}
91         os.Args = append(args, "-config", tmpfile.Name())
92         listener = nil
93         go main()
94         waitForListener()
95 }
96
97 func clearCache(c *C) {
98         err := os.RemoveAll(theConfig.CacheDirPath)
99         c.Check(err, IsNil)
100 }
101
102 func waitForListener() {
103         const (
104                 ms = 5
105         )
106         for i := 0; listener == nil && i < 10000; i += ms {
107                 time.Sleep(ms * time.Millisecond)
108         }
109         if listener == nil {
110                 log.Fatalf("Timed out waiting for listener to start")
111         }
112 }
113
114 func (s *ServerNotRequiredSuite) SetUpTest(c *C) {
115         // Discard standard log output
116         log.SetOutput(ioutil.Discard)
117 }
118
119 func (s *ServerRequiredSuite) SetUpTest(c *C) {
120         // Discard standard log output
121         log.SetOutput(ioutil.Discard)
122 }
123
124 func (s *ServerRequiredSuite) TearDownSuite(c *C) {
125         log.SetOutput(os.Stderr)
126 }
127
128 func (s *ServerNotRequiredSuite) TearDownSuite(c *C) {
129         log.SetOutput(os.Stderr)
130 }
131
132 func (s *ServerRequiredSuite) TestResults(c *C) {
133         runServer(c)
134         clearCache(c)
135         defer closeListener()
136         defer os.Remove(tmpConfigFileName)
137
138         // Test the about handler
139         {
140                 client := http.Client{}
141                 req, err := http.NewRequest("GET",
142                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/about"),
143                         nil)
144                 resp, err := client.Do(req)
145                 c.Check(err, Equals, nil)
146                 c.Check(resp.StatusCode, Equals, 200)
147                 body, err := ioutil.ReadAll(resp.Body)
148                 c.Check(string(body), Matches, ".*\"Name\":\"Arvados Version Server\".*")
149         }
150
151         // Test the help handler
152         {
153                 client := http.Client{}
154                 req, err := http.NewRequest("GET",
155                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/help"),
156                         nil)
157                 resp, err := client.Do(req)
158                 c.Check(err, Equals, nil)
159                 c.Check(resp.StatusCode, Equals, 200)
160                 body, err := ioutil.ReadAll(resp.Body)
161                 c.Check(string(body), Matches, ".*\"Usage\":\"GET /v1/commit/ or GET /v1/commit/git-commit or GET /v1/about or GET /v1/help\".*")
162         }
163
164         // Check the arvados-src version string for the first commit
165         {
166                 client := http.Client{}
167                 req, err := http.NewRequest("GET",
168                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/155848c15844554a5d5fd50f9577aa2e19767d9e"),
169                         nil)
170                 resp, err := client.Do(req)
171                 c.Check(err, Equals, nil)
172                 c.Check(resp.StatusCode, Equals, 200)
173                 body, err := ioutil.ReadAll(resp.Body)
174                 c.Check(string(body), Matches, ".*\"arvados-src\":\"0.1.20130104011935.155848c\".*")
175         }
176
177         // Check the arvados-src version string for a more recent commit
178         {
179                 client := http.Client{}
180                 req, err := http.NewRequest("GET",
181                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/9c1a28719df89a68b83cee07e3e0ab87c1712f69"),
182                         nil)
183                 resp, err := client.Do(req)
184                 c.Check(err, Equals, nil)
185                 c.Check(resp.StatusCode, Equals, 200)
186                 body, err := ioutil.ReadAll(resp.Body)
187                 c.Check(string(body), Matches, ".*\"arvados-src\":\"0.1.20161208152419.9c1a287\".*")
188         }
189
190         // Check the arvados-src version string for a weirdly truncated commit
191         {
192                 client := http.Client{}
193                 req, err := http.NewRequest("GET",
194                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/9c1a28719df89"),
195                         nil)
196                 resp, err := client.Do(req)
197                 c.Check(err, Equals, nil)
198                 c.Check(resp.StatusCode, Equals, 200)
199                 body, err := ioutil.ReadAll(resp.Body)
200                 c.Check(string(body), Matches, ".*\"arvados-src\":\"0.1.20161208152419.9c1a287\".*")
201         }
202
203         // Check an invalid request hash
204         {
205                 client := http.Client{}
206                 req, err := http.NewRequest("GET",
207                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/____"),
208                         nil)
209                 resp, err := client.Do(req)
210                 c.Check(err, Equals, nil)
211                 c.Check(resp.StatusCode, Equals, 200)
212                 body, err := ioutil.ReadAll(resp.Body)
213                 c.Check(string(body), Matches, ".*\"Type\":\"Error\".*")
214                 c.Check(string(body), Matches, ".*\"Msg\":\"Invalid RequestHash\".*")
215         }
216
217         // Check an invalid request hash of improper length
218         {
219                 client := http.Client{}
220                 req, err := http.NewRequest("GET",
221                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
222                         nil)
223                 resp, err := client.Do(req)
224                 c.Check(err, Equals, nil)
225                 c.Check(resp.StatusCode, Equals, 200)
226                 body, err := ioutil.ReadAll(resp.Body)
227                 c.Check(string(body), Matches, ".*\"Type\":\"Error\".*")
228                 c.Check(string(body), Matches, ".*\"Msg\":\"There was an error checking out the requested revision\".*")
229         }
230
231         // Check the python-arvados-cwl-runner version string for a *merge* commit where the python sdk version takes precedence
232         // This does not test the "if pythonSDKTimestamp > packageTimestamp" conditional block in func pythonSDKVersionCheck
233         // which appears to be a consequence of the --first-parent argument we pass to git log (exactly why, I don't understand yet)
234         {
235                 client := http.Client{}
236                 req, err := http.NewRequest("GET",
237                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/965565ddc62635928a6b043158fd683738961c8c"),
238                         nil)
239                 resp, err := client.Do(req)
240                 c.Check(err, Equals, nil)
241                 c.Check(resp.StatusCode, Equals, 200)
242                 body, err := ioutil.ReadAll(resp.Body)
243                 c.Check(string(body), Matches, ".*\"python-arvados-cwl-runner\":\"1.0.20161216221537\".*")
244         }
245
246         // Check the python-arvados-cwl-runner version string for a non-merge commit where the python sdk version takes precedence
247         {
248                 client := http.Client{}
249                 req, err := http.NewRequest("GET",
250                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/697e73b0605b6c182f1051e97ed370d5afa7d954"),
251                         nil)
252                 resp, err := client.Do(req)
253                 c.Check(err, Equals, nil)
254                 c.Check(resp.StatusCode, Equals, 200)
255                 body, err := ioutil.ReadAll(resp.Body)
256                 c.Check(string(body), Matches, ".*\"python-arvados-cwl-runner\":\"1.0.20161216215418\".*")
257         }
258
259         // Check passing 'master' as revision
260         {
261                 client := http.Client{}
262                 req, err := http.NewRequest("GET",
263                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/master"),
264                         nil)
265                 resp, err := client.Do(req)
266                 c.Check(err, Equals, nil)
267                 c.Check(resp.StatusCode, Equals, 200)
268                 _, err = ioutil.ReadAll(resp.Body)
269                 //              c.Check(string(body), Matches, ".*\"python-arvados-cwl-runner\":\"1.0.20161216215418\".*")
270         }
271
272         // Check passing '' as revision
273         {
274                 client := http.Client{}
275                 req, err := http.NewRequest("GET",
276                         fmt.Sprintf("http://%s/%s", listener.Addr().String(), "v1/commit/"),
277                         nil)
278                 resp, err := client.Do(req)
279                 c.Check(err, Equals, nil)
280                 c.Check(resp.StatusCode, Equals, 200)
281                 _, err = ioutil.ReadAll(resp.Body)
282                 //              c.Check(string(body), Matches, ".*\"python-arvados-cwl-runner\":\"1.0.20161216215418\".*")
283         }
284
285 }