-
Notifications
You must be signed in to change notification settings - Fork 60
/
health_test.go
153 lines (124 loc) · 3.95 KB
/
health_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package health
import (
"context"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
const (
checkErr = "failed during RabbitMQ health check"
)
func TestRegisterWithNoName(t *testing.T) {
h, err := New()
require.NoError(t, err)
err = h.Register(Config{
Name: "",
Check: func(context.Context) error {
return nil
},
})
require.Error(t, err, "health check registration with empty name should return an error")
}
func TestDoubleRegister(t *testing.T) {
h, err := New()
require.NoError(t, err)
healthCheckName := "health-check"
conf := Config{
Name: healthCheckName,
Check: func(context.Context) error {
return nil
},
}
err = h.Register(conf)
require.NoError(t, err, "the first registration of a health check should not return an error, but got one")
err = h.Register(conf)
assert.Error(t, err, "the second registration of a health check config should return an error, but did not")
err = h.Register(Config{
Name: healthCheckName,
Check: func(context.Context) error {
return errors.New("health checks registered")
},
})
assert.Error(t, err, "registration with same name, but different details should still return an error, but did not")
}
func TestHealthHandler(t *testing.T) {
h, err := New()
require.NoError(t, err)
res := httptest.NewRecorder()
req, err := http.NewRequest("GET", "http://localhost/status", nil)
require.NoError(t, err)
err = h.Register(Config{
Name: "rabbitmq",
SkipOnErr: true,
Check: func(context.Context) error { return errors.New(checkErr) },
})
require.NoError(t, err)
err = h.Register(Config{
Name: "mongodb",
Check: func(context.Context) error { return nil },
})
require.NoError(t, err)
err = h.Register(Config{
Name: "snail-service",
SkipOnErr: true,
Timeout: time.Second * 1,
Check: func(context.Context) error {
time.Sleep(time.Second * 2)
return nil
},
})
require.NoError(t, err)
handler := h.Handler()
handler.ServeHTTP(res, req)
assert.Equal(t, http.StatusOK, res.Code, "status handler returned wrong status code")
body := make(map[string]interface{})
err = json.NewDecoder(res.Body).Decode(&body)
require.NoError(t, err)
assert.Equal(t, string(StatusPartiallyAvailable), body["status"], "body returned wrong status")
failure, ok := body["failures"]
assert.True(t, ok, "body returned nil failures field")
f, ok := failure.(map[string]interface{})
assert.True(t, ok, "body returned nil failures.rabbitmq field")
assert.Equal(t, checkErr, f["rabbitmq"], "body returned wrong status for rabbitmq")
assert.Equal(t, string(StatusTimeout), f["snail-service"], "body returned wrong status for snail-service")
}
func TestHealth_Measure(t *testing.T) {
h, err := New(WithChecks(Config{
Name: "check1",
Timeout: time.Second,
SkipOnErr: false,
Check: func(context.Context) error {
time.Sleep(time.Second * 10)
return errors.New("check1")
},
}, Config{
Name: "check2",
Timeout: time.Second * 2,
SkipOnErr: false,
Check: func(context.Context) error {
time.Sleep(time.Second * 10)
return errors.New("check2")
},
}), WithMaxConcurrent(2))
require.NoError(t, err)
startedAt := time.Now()
result := h.Measure(context.Background())
elapsed := time.Since(startedAt)
// both checks should run concurrently and should fail with timeout,
// so should take not less than 2 sec, but less than 5 that is sequential check time
require.GreaterOrEqual(t, elapsed.Milliseconds(), (time.Second * 2).Milliseconds())
require.Less(t, elapsed.Milliseconds(), (time.Second * 5).Milliseconds())
assert.Equal(t, StatusUnavailable, result.Status)
assert.Equal(t, string(StatusTimeout), result.Failures["check1"])
assert.Equal(t, string(StatusTimeout), result.Failures["check2"])
assert.Nil(t, result.System)
h, err = New(WithSystemInfo())
require.NoError(t, err)
result = h.Measure(context.Background())
assert.NotNil(t, result.System)
}