Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0181226

Browse files
committed
feat(healthcheck): add accessurl check
1 parentfa5387c commit0181226

File tree

6 files changed

+242
-45
lines changed

6 files changed

+242
-45
lines changed

‎coderd/healthcheck/accessurl.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package healthcheck
2+
3+
import (
4+
"context"
5+
"io"
6+
"net/http"
7+
"net/url"
8+
"time"
9+
10+
"golang.org/x/xerrors"
11+
)
12+
13+
typeAccessURLReportstruct {
14+
Healthybool
15+
Reachablebool
16+
StatusCodeint
17+
HealthzResponsestring
18+
Errerror
19+
}
20+
21+
typeAccessURLOptionsstruct {
22+
AccessURL*url.URL
23+
Client*http.Client
24+
}
25+
26+
func (r*AccessURLReport)Run(ctx context.Context,opts*AccessURLOptions) {
27+
ctx,cancel:=context.WithTimeout(ctx,5*time.Second)
28+
defercancel()
29+
30+
ifopts.Client==nil {
31+
opts.Client=http.DefaultClient
32+
}
33+
34+
accessURL,err:=opts.AccessURL.Parse("/healthz")
35+
iferr!=nil {
36+
r.Err=xerrors.Errorf("parse healthz endpoint: %w",err)
37+
return
38+
}
39+
40+
req,err:=http.NewRequestWithContext(ctx,"GET",accessURL.String(),nil)
41+
iferr!=nil {
42+
r.Err=xerrors.Errorf("create healthz request: %w",err)
43+
return
44+
}
45+
46+
res,err:=opts.Client.Do(req)
47+
iferr!=nil {
48+
r.Err=xerrors.Errorf("get healthz endpoint: %w",err)
49+
return
50+
}
51+
deferres.Body.Close()
52+
53+
body,err:=io.ReadAll(res.Body)
54+
iferr!=nil {
55+
r.Err=xerrors.Errorf("read healthz response: %w",err)
56+
return
57+
}
58+
59+
r.Reachable=true
60+
r.Healthy=res.StatusCode==http.StatusOK
61+
r.StatusCode=res.StatusCode
62+
r.HealthzResponse=string(body)
63+
}

‎coderd/healthcheck/accessurl_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package healthcheck_test
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"net/http/httptest"
7+
"net/url"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
"golang.org/x/xerrors"
13+
14+
"github.com/coder/coder/coderd/coderdtest"
15+
"github.com/coder/coder/coderd/healthcheck"
16+
)
17+
18+
funcTestAccessURL(t*testing.T) {
19+
t.Parallel()
20+
21+
t.Run("OK",func(t*testing.T) {
22+
t.Parallel()
23+
24+
var (
25+
ctx,cancel=context.WithCancel(context.Background())
26+
report healthcheck.AccessURLReport
27+
client=coderdtest.New(t,nil)
28+
)
29+
defercancel()
30+
31+
report.Run(ctx,&healthcheck.AccessURLOptions{
32+
AccessURL:client.URL,
33+
})
34+
35+
assert.True(t,report.Healthy)
36+
assert.True(t,report.Reachable)
37+
assert.Equal(t,http.StatusOK,report.StatusCode)
38+
assert.Equal(t,"OK",report.HealthzResponse)
39+
assert.NoError(t,report.Err)
40+
})
41+
42+
t.Run("404",func(t*testing.T) {
43+
t.Parallel()
44+
45+
var (
46+
ctx,cancel=context.WithCancel(context.Background())
47+
report healthcheck.AccessURLReport
48+
resp= []byte("NOT OK")
49+
srv=httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
50+
w.WriteHeader(http.StatusNotFound)
51+
w.Write(resp)
52+
}))
53+
)
54+
defercancel()
55+
defersrv.Close()
56+
57+
u,err:=url.Parse(srv.URL)
58+
require.NoError(t,err)
59+
60+
report.Run(ctx,&healthcheck.AccessURLOptions{
61+
Client:srv.Client(),
62+
AccessURL:u,
63+
})
64+
65+
assert.False(t,report.Healthy)
66+
assert.True(t,report.Reachable)
67+
assert.Equal(t,http.StatusNotFound,report.StatusCode)
68+
assert.Equal(t,string(resp),report.HealthzResponse)
69+
assert.NoError(t,report.Err)
70+
})
71+
72+
t.Run("ClientErr",func(t*testing.T) {
73+
t.Parallel()
74+
75+
var (
76+
ctx,cancel=context.WithCancel(context.Background())
77+
report healthcheck.AccessURLReport
78+
resp= []byte("OK")
79+
srv=httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter,r*http.Request) {
80+
w.WriteHeader(http.StatusOK)
81+
w.Write(resp)
82+
}))
83+
client=srv.Client()
84+
)
85+
defercancel()
86+
defersrv.Close()
87+
88+
expErr:=xerrors.New("client error")
89+
client.Transport=roundTripFunc(func(r*http.Request) (*http.Response,error) {
90+
returnnil,expErr
91+
})
92+
93+
u,err:=url.Parse(srv.URL)
94+
require.NoError(t,err)
95+
96+
report.Run(ctx,&healthcheck.AccessURLOptions{
97+
Client:client,
98+
AccessURL:u,
99+
})
100+
101+
assert.False(t,report.Healthy)
102+
assert.False(t,report.Reachable)
103+
assert.Equal(t,0,report.StatusCode)
104+
assert.Equal(t,"",report.HealthzResponse)
105+
assert.ErrorIs(t,report.Err,expErr)
106+
})
107+
}
108+
109+
typeroundTripFuncfunc(r*http.Request) (*http.Response,error)
110+
111+
func (rtroundTripFunc)RoundTrip(r*http.Request) (*http.Response,error) {
112+
returnrt(r)
113+
}

‎coderd/healthcheck/derp.go

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type DERPReport struct {
3030
Regionsmap[int]*DERPRegionReport`json:"regions"`
3131

3232
Netcheck*netcheck.Report`json:"netcheck"`
33+
NetcheckErrerror`json:"netcheck_err"`
3334
NetcheckLogs []string`json:"netcheck_logs"`
3435
}
3536

@@ -66,32 +67,30 @@ type DERPReportOptions struct {
6667
DERPMap*tailcfg.DERPMap
6768
}
6869

69-
func (r*DERPReport)Run(ctx context.Context,opts*DERPReportOptions)error{
70+
func (r*DERPReport)Run(ctx context.Context,opts*DERPReportOptions) {
7071
r.Healthy=true
7172
r.Regions=map[int]*DERPRegionReport{}
7273

73-
eg,ctx:=errgroup.WithContext(ctx)
74+
wg:=&sync.WaitGroup{}
7475

76+
wg.Add(len(opts.DERPMap.Regions))
7577
for_,region:=rangeopts.DERPMap.Regions {
7678
region:=region
77-
eg.Go(func()error {
79+
gofunc() {
80+
deferwg.Done()
7881
regionReport:=DERPRegionReport{
7982
Region:region,
8083
}
8184

82-
err:=regionReport.Run(ctx)
83-
iferr!=nil {
84-
returnxerrors.Errorf("run region report: %w",err)
85-
}
85+
regionReport.Run(ctx)
8686

8787
r.mu.Lock()
8888
r.Regions[region.RegionID]=&regionReport
8989
if!regionReport.Healthy {
9090
r.Healthy=false
9191
}
9292
r.mu.Unlock()
93-
returnnil
94-
})
93+
}()
9594
}
9695

9796
ncLogf:=func(formatstring,args...interface{}) {
@@ -103,44 +102,40 @@ func (r *DERPReport) Run(ctx context.Context, opts *DERPReportOptions) error {
103102
PortMapper:portmapper.NewClient(tslogger.WithPrefix(ncLogf,"portmap: "),nil),
104103
Logf:tslogger.WithPrefix(ncLogf,"netcheck: "),
105104
}
106-
ncReport,err:=nc.GetReport(ctx,opts.DERPMap)
107-
iferr!=nil {
108-
returnxerrors.Errorf("run netcheck: %w",err)
109-
}
110-
r.Netcheck=ncReport
105+
r.Netcheck,r.NetcheckErr=nc.GetReport(ctx,opts.DERPMap)
111106

112-
returneg.Wait()
107+
wg.Wait()
113108
}
114109

115-
func (r*DERPRegionReport)Run(ctx context.Context)error{
110+
func (r*DERPRegionReport)Run(ctx context.Context) {
116111
r.Healthy=true
117112
r.NodeReports= []*DERPNodeReport{}
118-
eg,ctx:=errgroup.WithContext(ctx)
119113

114+
wg:=&sync.WaitGroup{}
115+
116+
wg.Add(len(r.Region.Nodes))
120117
for_,node:=ranger.Region.Nodes {
121118
node:=node
122-
eg.Go(func()error {
119+
gofunc() {
120+
deferwg.Done()
121+
123122
nodeReport:=DERPNodeReport{
124123
Node:node,
125124
Healthy:true,
126125
}
127126

128-
err:=nodeReport.Run(ctx)
129-
iferr!=nil {
130-
returnxerrors.Errorf("run node report: %w",err)
131-
}
127+
nodeReport.Run(ctx)
132128

133129
r.mu.Lock()
134130
r.NodeReports=append(r.NodeReports,&nodeReport)
135131
if!nodeReport.Healthy {
136132
r.Healthy=false
137133
}
138134
r.mu.Unlock()
139-
returnnil
140-
})
135+
}()
141136
}
142137

143-
returneg.Wait()
138+
wg.Wait()
144139
}
145140

146141
func (r*DERPNodeReport)derpURL()*url.URL {
@@ -159,7 +154,7 @@ func (r *DERPNodeReport) derpURL() *url.URL {
159154
returnderpURL
160155
}
161156

162-
func (r*DERPNodeReport)Run(ctx context.Context)error{
157+
func (r*DERPNodeReport)Run(ctx context.Context) {
163158
ctx,cancel:=context.WithTimeout(ctx,10*time.Second)
164159
defercancel()
165160

@@ -179,7 +174,6 @@ func (r *DERPNodeReport) Run(ctx context.Context) error {
179174
r.STUN.Error!=nil {
180175
r.Healthy=false
181176
}
182-
returnnil
183177
}
184178

185179
func (r*DERPNodeReport)doExchangeMessage(ctx context.Context) {

‎coderd/healthcheck/derp_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ func TestDERP(t *testing.T) {
5858
}
5959
)
6060

61-
err:=report.Run(ctx,opts)
62-
require.NoError(t,err)
61+
report.Run(ctx,opts)
6362

6463
assert.True(t,report.Healthy)
6564
for_,region:=rangereport.Regions {
@@ -100,8 +99,7 @@ func TestDERP(t *testing.T) {
10099
// Only include the Dallas region
101100
opts.DERPMap.Regions=map[int]*tailcfg.DERPRegion{9:opts.DERPMap.Regions[9]}
102101

103-
err:=report.Run(ctx,opts)
104-
require.NoError(t,err)
102+
report.Run(ctx,opts)
105103

106104
assert.True(t,report.Healthy)
107105
for_,region:=rangereport.Regions {
@@ -215,8 +213,7 @@ func TestDERP(t *testing.T) {
215213
}
216214
)
217215

218-
err:=report.Run(ctx,opts)
219-
require.NoError(t,err)
216+
report.Run(ctx,opts)
220217

221218
assert.True(t,report.Healthy)
222219
for_,region:=rangereport.Regions {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp