Skip to content

Commit 185a915

Browse files
committed
feat(codersdk/healthsdk): add Summarize() method
1 parent 3fa77ce commit 185a915

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed

codersdk/healthsdk/healthsdk.go

+43
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"net/http"
7+
"strings"
78
"time"
89

910
"golang.org/x/xerrors"
@@ -118,6 +119,18 @@ type HealthcheckReport struct {
118119
CoderVersion string `json:"coder_version"`
119120
}
120121

122+
// Summarize returns a summary of all errors and warnings of components of HealthcheckReport.
123+
func (r *HealthcheckReport) Summarize() []string {
124+
var msgs []string
125+
msgs = append(msgs, r.AccessURL.Summarize("Access URL:")...)
126+
msgs = append(msgs, r.Database.Summarize("Database:")...)
127+
msgs = append(msgs, r.DERP.Summarize("DERP:")...)
128+
msgs = append(msgs, r.ProvisionerDaemons.Summarize("Provisioner Daemons:")...)
129+
msgs = append(msgs, r.Websocket.Summarize("Websocket:")...)
130+
msgs = append(msgs, r.WorkspaceProxy.Summarize("Workspace Proxies:")...)
131+
return msgs
132+
}
133+
121134
// BaseReport holds fields common to various health reports.
122135
type BaseReport struct {
123136
// Healthy is deprecated and left for backward compatibility purposes, use `Severity` instead.
@@ -128,6 +141,36 @@ type BaseReport struct {
128141
Dismissed bool `json:"dismissed"`
129142
}
130143

144+
// Summarize returns a list of strings containing the errors and warnings of BaseReport, if present.
145+
// All strings are prefixed with prefix.
146+
func (b *BaseReport) Summarize(prefix string) []string {
147+
if b == nil {
148+
return []string{}
149+
}
150+
var msgs []string
151+
if b.Error != nil {
152+
var sb strings.Builder
153+
if prefix != "" {
154+
_, _ = sb.WriteString(prefix)
155+
_, _ = sb.WriteString(" ")
156+
}
157+
_, _ = sb.WriteString("Error: ")
158+
_, _ = sb.WriteString(*b.Error)
159+
msgs = append(msgs, sb.String())
160+
}
161+
for _, warn := range b.Warnings {
162+
var sb strings.Builder
163+
if prefix != "" {
164+
_, _ = sb.WriteString(prefix)
165+
_, _ = sb.WriteString(" ")
166+
}
167+
_, _ = sb.WriteString("Warn: ")
168+
_, _ = sb.WriteString(warn.String())
169+
msgs = append(msgs, sb.String())
170+
}
171+
return msgs
172+
}
173+
131174
// AccessURLReport shows the results of performing a HTTP_GET to the /healthz endpoint through the configured access URL.
132175
type AccessURLReport struct {
133176
BaseReport

codersdk/healthsdk/healthsdk_test.go

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package healthsdk_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
8+
"github.com/coder/coder/v2/coderd/healthcheck/health"
9+
"github.com/coder/coder/v2/coderd/util/ptr"
10+
"github.com/coder/coder/v2/codersdk/healthsdk"
11+
)
12+
13+
func TestSummarize(t *testing.T) {
14+
t.Parallel()
15+
16+
t.Run("HealthcheckReport", func(t *testing.T) {
17+
unhealthy := healthsdk.BaseReport{
18+
Error: ptr.Ref("test error"),
19+
Warnings: []health.Message{{Code: "TEST", Message: "testing"}},
20+
}
21+
hr := healthsdk.HealthcheckReport{
22+
AccessURL: healthsdk.AccessURLReport{
23+
BaseReport: unhealthy,
24+
},
25+
Database: healthsdk.DatabaseReport{
26+
BaseReport: unhealthy,
27+
},
28+
DERP: healthsdk.DERPHealthReport{
29+
BaseReport: unhealthy,
30+
},
31+
ProvisionerDaemons: healthsdk.ProvisionerDaemonsReport{
32+
BaseReport: unhealthy,
33+
},
34+
Websocket: healthsdk.WebsocketReport{
35+
BaseReport: unhealthy,
36+
},
37+
WorkspaceProxy: healthsdk.WorkspaceProxyReport{
38+
BaseReport: unhealthy,
39+
},
40+
}
41+
expected := []string{
42+
"Access URL: Error: test error",
43+
"Access URL: Warn: TEST: testing",
44+
"Database: Error: test error",
45+
"Database: Warn: TEST: testing",
46+
"DERP: Error: test error",
47+
"DERP: Warn: TEST: testing",
48+
"Provisioner Daemons: Error: test error",
49+
"Provisioner Daemons: Warn: TEST: testing",
50+
"Websocket: Error: test error",
51+
"Websocket: Warn: TEST: testing",
52+
"Workspace Proxies: Error: test error",
53+
"Workspace Proxies: Warn: TEST: testing",
54+
}
55+
actual := hr.Summarize()
56+
assert.Equal(t, expected, actual)
57+
})
58+
59+
for _, tt := range []struct {
60+
name string
61+
br healthsdk.BaseReport
62+
pfx string
63+
expected []string
64+
}{
65+
{
66+
name: "empty",
67+
br: healthsdk.BaseReport{},
68+
pfx: "",
69+
expected: []string{},
70+
},
71+
{
72+
name: "no prefix",
73+
br: healthsdk.BaseReport{
74+
Error: ptr.Ref("testing"),
75+
Warnings: []health.Message{
76+
{
77+
Code: "TEST01",
78+
Message: "testing one",
79+
},
80+
{
81+
Code: "TEST02",
82+
Message: "testing two",
83+
},
84+
},
85+
},
86+
pfx: "",
87+
expected: []string{
88+
"Error: testing",
89+
"Warn: TEST01: testing one",
90+
"Warn: TEST02: testing two",
91+
},
92+
},
93+
{
94+
name: "prefix",
95+
br: healthsdk.BaseReport{
96+
Error: ptr.Ref("testing"),
97+
Warnings: []health.Message{
98+
{
99+
Code: "TEST01",
100+
Message: "testing one",
101+
},
102+
{
103+
Code: "TEST02",
104+
Message: "testing two",
105+
},
106+
},
107+
},
108+
pfx: "TEST:",
109+
expected: []string{
110+
"TEST: Error: testing",
111+
"TEST: Warn: TEST01: testing one",
112+
"TEST: Warn: TEST02: testing two",
113+
},
114+
},
115+
} {
116+
tt := tt
117+
t.Run(tt.name, func(t *testing.T) {
118+
t.Parallel()
119+
actual := tt.br.Summarize(tt.pfx)
120+
if len(tt.expected) == 0 {
121+
assert.Empty(t, actual)
122+
return
123+
}
124+
assert.Equal(t, tt.expected, actual)
125+
})
126+
}
127+
}

0 commit comments

Comments
 (0)