14860: Exposes the bug with a new test.
[arvados.git] / services / ws / 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         "encoding/json"
9         "io/ioutil"
10         "net/http"
11         "sync"
12         "time"
13
14         "git.curoverse.com/arvados.git/sdk/go/arvados"
15         "git.curoverse.com/arvados.git/sdk/go/arvadostest"
16         check "gopkg.in/check.v1"
17 )
18
19 var _ = check.Suite(&serverSuite{})
20
21 type serverSuite struct {
22         cfg *wsConfig
23         srv *server
24         wg  sync.WaitGroup
25 }
26
27 func (s *serverSuite) SetUpTest(c *check.C) {
28         s.cfg = s.testConfig()
29         s.srv = &server{wsConfig: s.cfg}
30 }
31
32 func (*serverSuite) testConfig() *wsConfig {
33         cfg := defaultConfig()
34         cfg.Client = *(arvados.NewClientFromEnv())
35         cfg.Postgres = testDBConfig()
36         cfg.Listen = ":"
37         cfg.ManagementToken = arvadostest.ManagementToken
38         return &cfg
39 }
40
41 // TestBadDB ensures Run() returns an error (instead of panicking or
42 // deadlocking) if it can't connect to the database server at startup.
43 func (s *serverSuite) TestBadDB(c *check.C) {
44         s.cfg.Postgres["password"] = "1234"
45
46         var wg sync.WaitGroup
47         wg.Add(1)
48         go func() {
49                 err := s.srv.Run()
50                 c.Check(err, check.NotNil)
51                 wg.Done()
52         }()
53         wg.Add(1)
54         go func() {
55                 s.srv.WaitReady()
56                 wg.Done()
57         }()
58
59         done := make(chan bool)
60         go func() {
61                 wg.Wait()
62                 close(done)
63         }()
64         select {
65         case <-done:
66         case <-time.After(10 * time.Second):
67                 c.Fatal("timeout")
68         }
69 }
70
71 func (s *serverSuite) TestHealth(c *check.C) {
72         go s.srv.Run()
73         defer s.srv.Close()
74         s.srv.WaitReady()
75         for _, token := range []string{"", "foo", s.cfg.ManagementToken} {
76                 req, err := http.NewRequest("GET", "http://"+s.srv.listener.Addr().String()+"/_health/ping", nil)
77                 c.Assert(err, check.IsNil)
78                 if token != "" {
79                         req.Header.Add("Authorization", "Bearer "+token)
80                 }
81                 resp, err := http.DefaultClient.Do(req)
82                 c.Check(err, check.IsNil)
83                 if token == s.cfg.ManagementToken {
84                         c.Check(resp.StatusCode, check.Equals, http.StatusOK)
85                         buf, err := ioutil.ReadAll(resp.Body)
86                         c.Check(err, check.IsNil)
87                         c.Check(string(buf), check.Equals, `{"health":"OK"}`+"\n")
88                 } else {
89                         c.Check(resp.StatusCode, check.Not(check.Equals), http.StatusOK)
90                 }
91         }
92 }
93
94 func (s *serverSuite) TestStatus(c *check.C) {
95         go s.srv.Run()
96         defer s.srv.Close()
97         s.srv.WaitReady()
98         req, err := http.NewRequest("GET", "http://"+s.srv.listener.Addr().String()+"/status.json", nil)
99         c.Assert(err, check.IsNil)
100         resp, err := http.DefaultClient.Do(req)
101         c.Check(err, check.IsNil)
102         c.Check(resp.StatusCode, check.Equals, http.StatusOK)
103         var status map[string]interface{}
104         err = json.NewDecoder(resp.Body).Decode(&status)
105         c.Check(err, check.IsNil)
106         c.Check(status["Version"], check.Not(check.Equals), "")
107 }
108
109 func (s *serverSuite) TestHealthDisabled(c *check.C) {
110         s.cfg.ManagementToken = ""
111
112         go s.srv.Run()
113         defer s.srv.Close()
114         s.srv.WaitReady()
115
116         for _, token := range []string{"", "foo", arvadostest.ManagementToken} {
117                 req, err := http.NewRequest("GET", "http://"+s.srv.listener.Addr().String()+"/_health/ping", nil)
118                 c.Assert(err, check.IsNil)
119                 req.Header.Add("Authorization", "Bearer "+token)
120                 resp, err := http.DefaultClient.Do(req)
121                 c.Check(err, check.IsNil)
122                 c.Check(resp.StatusCode, check.Equals, http.StatusNotFound)
123         }
124 }