Skip to content
This repository was archived by the owner on Nov 14, 2024. It is now read-only.

Commit 5a26ffc

Browse files
committed
more tests
1 parent 84882af commit 5a26ffc

File tree

15 files changed

+176
-68
lines changed

15 files changed

+176
-68
lines changed

internal/api/types.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type Checker interface {
1919
// Run runs the checks and returns the results.
2020
//
2121
// This method will run through the checks and return results.
22-
Run(context.Context) CheckResults
22+
Run(context.Context) error
2323
}
2424

2525
var _ = fmt.Stringer(StatePassed)
@@ -57,15 +57,15 @@ func (s CheckState) MustEmoji() string {
5757
func (s CheckState) Emoji() (string, error) {
5858
switch s {
5959
case StatePassed:
60-
return "", nil
60+
return "👍", nil
6161
case StateWarning:
6262
return "⚠️", nil
6363
case StateFailed:
64-
return "", nil
64+
return "👎", nil
6565
case StateInfo:
66-
return "ℹ️", nil
66+
return "🔔", nil
6767
case StateSkipped:
68-
return "🤔", nil
68+
return "", nil
6969
}
7070

7171
return "", xerrors.Errorf("unknown state: %d", s)
@@ -119,5 +119,3 @@ type CheckResult struct {
119119
Summary string
120120
Details map[string]interface{}
121121
}
122-
123-
type CheckResults []*CheckResult

internal/api/types_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,20 @@ func TestKnownStates(t *testing.T) {
1919
}
2020

2121
for _, state := range states {
22+
state := state
23+
2224
t.Run(state.String(), func(t *testing.T) {
25+
t.Parallel()
26+
2327
emoji, err := state.Emoji()
2428
assert.Success(t, "state.Emoji() error non-nil", err)
2529
assert.True(t, "state.Emoji() is non-empty", len(emoji) > 0)
30+
_ = state.MustEmoji()
2631

2732
text, err := state.Text()
2833
assert.Success(t, "state.Text() error non-nil", err)
2934
assert.True(t, "state.Text() is non-empty", len(text) > 0)
35+
_ = state.MustText()
3036

3137
str := state.String()
3238
assert.True(t, "state.String() is non-empty", len(str) > 0)

internal/api/writer.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package api
22

3+
var _ = ResultWriter(&DiscardWriter{})
4+
35
// ResultWriter writes the given result to a configured output.
46
type ResultWriter interface {
5-
WriteResult(result *CheckResult) error
7+
WriteResult(*CheckResult) error
68
}
79

810
// DiscardWriter is a writer that discards all results.
911
type DiscardWriter struct {
1012
}
1113

12-
func (*DiscardWriter) WriteResult(result *CheckResult) error {
14+
func (*DiscardWriter) WriteResult(_ *CheckResult) error {
1315
return nil
1416
}

internal/api/writer_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"github.com/cdr/coder-doctor/internal/api"
88
)
99

10-
var _ = api.ResultWriter(&api.DiscardWriter{})
11-
1210
func TestDiscardWriter(t *testing.T) {
1311
t.Parallel()
1412

internal/checks/kube/kubernetes.go

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,33 @@ import (
44
"context"
55
"io"
66

7-
"cdr.dev/slog"
8-
"cdr.dev/slog/sloggers/sloghuman"
97
"github.com/Masterminds/semver/v3"
108
"k8s.io/client-go/kubernetes"
119

10+
"cdr.dev/slog"
11+
"cdr.dev/slog/sloggers/sloghuman"
12+
1213
"github.com/cdr/coder-doctor/internal/api"
1314
)
1415

1516
var _ = api.Checker(&KubernetesChecker{})
1617

1718
type KubernetesChecker struct {
1819
client kubernetes.Interface
20+
writer api.ResultWriter
1921
coderVersion *semver.Version
2022
log slog.Logger
2123
}
2224

23-
type KubernetesCheckOption func(k *KubernetesChecker)
25+
type Option func(k *KubernetesChecker)
2426

25-
func NewKubernetesChecker(opts ...KubernetesCheckOption) *KubernetesChecker {
27+
func NewKubernetesChecker(client kubernetes.Interface, opts ...Option) *KubernetesChecker {
2628
checker := &KubernetesChecker{
27-
log: slog.Make(sloghuman.Sink(io.Discard)),
29+
client: client,
30+
log: slog.Make(sloghuman.Sink(io.Discard)),
31+
writer: &api.DiscardWriter{},
32+
// Select the newest version by default
33+
coderVersion: semver.MustParse("100.0.0"),
2834
}
2935

3036
for _, opt := range opts {
@@ -34,30 +40,38 @@ func NewKubernetesChecker(opts ...KubernetesCheckOption) *KubernetesChecker {
3440
return checker
3541
}
3642

37-
func (*KubernetesChecker) Validate() error {
38-
return nil
39-
}
40-
41-
func (k *KubernetesChecker) Run(ctx context.Context) api.CheckResults {
42-
return api.CheckResults{
43-
k.CheckVersion(ctx),
43+
func WithWriter(writer api.ResultWriter) Option {
44+
return func(k *KubernetesChecker) {
45+
k.writer = writer
4446
}
4547
}
4648

47-
func WithClient(client kubernetes.Interface) KubernetesCheckOption {
49+
func WithClient(client kubernetes.Interface) Option {
4850
return func(k *KubernetesChecker) {
4951
k.client = client
5052
}
5153
}
5254

53-
func WithCoderVersion(version *semver.Version) KubernetesCheckOption {
55+
func WithCoderVersion(version *semver.Version) Option {
5456
return func(k *KubernetesChecker) {
5557
k.coderVersion = version
5658
}
5759
}
5860

59-
func WithLogger(log slog.Logger) KubernetesCheckOption {
61+
func WithLogger(log slog.Logger) Option {
6062
return func(k *KubernetesChecker) {
6163
k.log = log
6264
}
6365
}
66+
67+
func (*KubernetesChecker) Validate() error {
68+
return nil
69+
}
70+
71+
func (k *KubernetesChecker) Run(ctx context.Context) error {
72+
err := k.writer.WriteResult(k.CheckVersion(ctx))
73+
if err != nil {
74+
return err
75+
}
76+
return nil
77+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package kube

internal/checks/kube/version.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import (
55
"encoding/json"
66
"fmt"
77

8-
"cdr.dev/slog"
98
"github.com/Masterminds/semver/v3"
109
"k8s.io/apimachinery/pkg/version"
1110

11+
"cdr.dev/slog"
12+
1213
"github.com/cdr/coder-doctor/internal/api"
1314
)
1415

internal/checks/kube/version_test.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,56 @@ func TestVersions(t *testing.T) {
115115
})
116116
assert.Success(t, "failed to create client", err)
117117

118-
checker := NewKubernetesChecker(WithClient(client), WithCoderVersion(test.CoderVersion))
118+
checker := NewKubernetesChecker(client, WithCoderVersion(test.CoderVersion))
119119
result := checker.CheckVersion(context.Background())
120120
assert.Equal(t, "check result matches", test.ExpectedResult, result)
121121
})
122122
}
123123
}
124124

125+
func TestUnknownRoute(t *testing.T) {
126+
t.Parallel()
127+
128+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
129+
w.Header().Set("Content-Type", "application/json")
130+
w.WriteHeader(http.StatusNotFound)
131+
}))
132+
defer server.Close()
133+
134+
client, err := kubernetes.NewForConfig(&rest.Config{
135+
Host: server.URL,
136+
})
137+
assert.Success(t, "failed to create client", err)
138+
139+
checker := NewKubernetesChecker(client)
140+
result := checker.CheckVersion(context.Background())
141+
assert.Equal(t, "failed check", api.StateFailed, result.State)
142+
assert.ErrorContains(t, "unknown route", result.Details["error"].(error), "the server could not find the requested resource")
143+
}
144+
145+
func TestCorruptResponse(t *testing.T) {
146+
t.Parallel()
147+
148+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
149+
w.Header().Set("Content-Type", "application/json")
150+
w.WriteHeader(http.StatusOK)
151+
err := json.NewEncoder(w).Encode(map[string]interface{}{
152+
"gitVersion": 10,
153+
})
154+
assert.Success(t, "failed to encode response", err)
155+
}))
156+
defer server.Close()
157+
158+
client, err := kubernetes.NewForConfig(&rest.Config{
159+
Host: server.URL,
160+
})
161+
assert.Success(t, "failed to create client", err)
162+
163+
checker := NewKubernetesChecker(client)
164+
result := checker.CheckVersion(context.Background())
165+
assert.Equal(t, "failed check", api.StateFailed, result.State)
166+
assert.ErrorContains(t, "unknown route", result.Details["error"].(error), "json: cannot unmarshal number into Go struct field Info.gitVersion of type string")
167+
}
125168
func TestNearestVersion(t *testing.T) {
126169
t.Parallel()
127170

internal/cmd/check/check.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package check
22

33
import (
4-
"github.com/cdr/coder-doctor/internal/cmd/check/kubernetes"
54
"github.com/spf13/cobra"
5+
6+
"github.com/cdr/coder-doctor/internal/cmd/check/kubernetes"
67
)
78

89
func NewCommand() *cobra.Command {

internal/cmd/check/kubernetes/kubernetes.go

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package kubernetes
22

33
import (
4+
"os"
5+
46
"github.com/Masterminds/semver/v3"
57
"github.com/spf13/cobra"
6-
"golang.org/x/xerrors"
78

89
"cdr.dev/slog"
910
"cdr.dev/slog/sloggers/sloghuman"
1011

11-
"k8s.io/client-go/kubernetes"
12+
kclient "k8s.io/client-go/kubernetes"
1213
// Kubernetes authentication plugins
1314
_ "k8s.io/client-go/plugin/pkg/client/auth/azure"
1415
_ "k8s.io/client-go/plugin/pkg/client/auth/exec"
@@ -78,7 +79,7 @@ func run(cmd *cobra.Command, _ []string) error {
7879
return err
7980
}
8081

81-
clientset, err := kubernetes.NewForConfig(config)
82+
clientset, err := kclient.NewForConfig(config)
8283
if err != nil {
8384
return err
8485
}
@@ -106,20 +107,15 @@ func run(cmd *cobra.Command, _ []string) error {
106107
}
107108

108109
checker := kube.NewKubernetesChecker(
109-
kube.WithClient(clientset),
110-
kube.WithCoderVersion(cv),
110+
clientset,
111111
kube.WithLogger(log),
112+
kube.WithCoderVersion(cv),
113+
kube.WithWriter(humanwriter.New(os.Stdout)),
112114
)
113115

114-
writer := humanwriter.New()
115-
116-
results := checker.Run(cmd.Context())
117-
for _, result := range results {
118-
err = writer.WriteResult(result)
119-
if err != nil {
120-
return xerrors.Errorf("failed to write results to stdout: %w", err)
121-
}
122-
116+
err = checker.Run(cmd.Context())
117+
if err != nil {
118+
return err
123119
}
124120

125121
return nil

0 commit comments

Comments
 (0)