20690: Merge branch 'main' into 20690-remove-wb1
[arvados.git] / lib / controller / rails_restart_test.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package controller
6
7 import (
8         "bytes"
9         "crypto/sha256"
10         "crypto/tls"
11         "fmt"
12         "io/ioutil"
13         "net/http"
14         "net/url"
15         "os"
16         "strings"
17         "time"
18
19         "git.arvados.org/arvados.git/lib/config"
20         "git.arvados.org/arvados.git/sdk/go/arvadostest"
21         "git.arvados.org/arvados.git/sdk/go/ctxlog"
22         check "gopkg.in/check.v1"
23 )
24
25 var _ = check.Suite(&railsRestartSuite{})
26
27 type railsRestartSuite struct{}
28
29 // This tests RailsAPI, not controller -- but tests RailsAPI's
30 // integration with passenger, so it needs to run against the
31 // run-tests.sh environment where RailsAPI runs under passenger, not
32 // in the Rails test environment.
33 func (s *railsRestartSuite) TestConfigReload(c *check.C) {
34         hc := http.Client{Transport: &http.Transport{
35                 TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
36         }}
37
38         confdata, err := os.ReadFile(os.Getenv("ARVADOS_CONFIG"))
39         c.Assert(err, check.IsNil)
40         oldhash := fmt.Sprintf("%x", sha256.Sum256(confdata))
41         c.Logf("oldhash %s", oldhash)
42
43         ldr := config.NewLoader(&bytes.Buffer{}, ctxlog.TestLogger(c))
44         cfg, err := ldr.Load()
45         c.Assert(err, check.IsNil)
46         cc, err := cfg.GetCluster("")
47         c.Assert(err, check.IsNil)
48         var metricsURL string
49         for u := range cc.Services.RailsAPI.InternalURLs {
50                 u := url.URL(u)
51                 mu, err := u.Parse("/metrics")
52                 c.Assert(err, check.IsNil)
53                 metricsURL = mu.String()
54         }
55
56         req, err := http.NewRequest(http.MethodGet, metricsURL, nil)
57         c.Assert(err, check.IsNil)
58         req.Header.Set("Authorization", "Bearer "+arvadostest.ManagementToken)
59
60         resp, err := hc.Do(req)
61         c.Assert(err, check.IsNil)
62         c.Check(resp.StatusCode, check.Equals, http.StatusOK)
63         body, err := ioutil.ReadAll(resp.Body)
64         c.Assert(err, check.IsNil)
65         c.Check(string(body), check.Matches, `(?ms).*`+oldhash+`.*`)
66
67         f, err := os.OpenFile(os.Getenv("ARVADOS_CONFIG"), os.O_WRONLY|os.O_APPEND, 0)
68         c.Assert(err, check.IsNil)
69         _, err = f.Write([]byte{'\n'})
70         c.Assert(err, check.IsNil)
71         err = f.Close()
72         c.Assert(err, check.IsNil)
73         newhash := fmt.Sprintf("%x", sha256.Sum256(append(confdata, '\n')))
74         c.Logf("newhash %s", newhash)
75
76         // Wait for RailsAPI's 1 Hz reload_config thread to poll and
77         // hit restart.txt
78         pollstart := time.Now()
79         for deadline := time.Now().Add(20 * time.Second); time.Now().Before(deadline); time.Sleep(time.Second) {
80                 resp, err = hc.Do(req)
81                 c.Assert(err, check.IsNil)
82                 defer resp.Body.Close()
83                 c.Check(resp.StatusCode, check.Equals, http.StatusOK)
84                 body, err = ioutil.ReadAll(resp.Body)
85                 c.Assert(err, check.IsNil)
86                 resp.Body.Close()
87                 if strings.Contains(string(body), newhash) {
88                         break
89                 }
90         }
91         c.Logf("waited %s for rails to restart", time.Now().Sub(pollstart))
92         c.Check(string(body), check.Matches, `(?ms).*`+newhash+`.*`)
93 }