master
go 227 lines 4.8 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 //go:build linux
4
5 package fail2ban
6
7 import (
8 "context"
9 "errors"
10 "os"
11 "testing"
12
13 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
14
15 "github.com/stretchr/testify/assert"
16 "github.com/stretchr/testify/require"
17 )
18
19 var (
20 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
21 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
22
23 dataStatus, _ = os.ReadFile("testdata/fail2ban-status.txt")
24 dataJailStatus, _ = os.ReadFile("testdata/fail2ban-jail-status.txt")
25 )
26
27 func Test_testDataIsValid(t *testing.T) {
28 for name, data := range map[string][]byte{
29 "dataConfigJSON": dataConfigJSON,
30 "dataConfigYAML": dataConfigYAML,
31
32 "dataStatus": dataStatus,
33 "dataJailStatus": dataJailStatus,
34 } {
35 require.NotNil(t, data, name)
36
37 }
38 }
39
40 func TestCollector_Configuration(t *testing.T) {
41 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
42 }
43
44 func TestCollector_Init(t *testing.T) {
45 tests := map[string]struct {
46 config Config
47 wantFail bool
48 }{
49 "success with default config": {
50 wantFail: false,
51 config: New().Config,
52 },
53 }
54
55 for name, test := range tests {
56 t.Run(name, func(t *testing.T) {
57 collr := New()
58 collr.Config = test.config
59
60 if test.wantFail {
61 assert.Error(t, collr.Init(context.Background()))
62 } else {
63 assert.NoError(t, collr.Init(context.Background()))
64 }
65 })
66 }
67 }
68
69 func TestCollector_Cleanup(t *testing.T) {
70 tests := map[string]struct {
71 prepare func() *Collector
72 }{
73 "not initialized exec": {
74 prepare: func() *Collector {
75 return New()
76 },
77 },
78 "after check": {
79 prepare: func() *Collector {
80 collr := New()
81 collr.exec = prepareMockOk()
82 _ = collr.Check(context.Background())
83 return collr
84 },
85 },
86 "after collect": {
87 prepare: func() *Collector {
88 collr := New()
89 collr.exec = prepareMockOk()
90 _ = collr.Collect(context.Background())
91 return collr
92 },
93 },
94 }
95
96 for name, test := range tests {
97 t.Run(name, func(t *testing.T) {
98 collr := test.prepare()
99
100 assert.NotPanics(t, func() { collr.Cleanup(context.Background()) })
101 })
102 }
103 }
104
105 func TestCollector_Charts(t *testing.T) {
106 assert.NotNil(t, New().Charts())
107 }
108
109 func TestCollector_Check(t *testing.T) {
110 tests := map[string]struct {
111 prepareMock func() *mockFail2BanClientCliExec
112 wantFail bool
113 }{
114 "success multiple jails": {
115 wantFail: false,
116 prepareMock: prepareMockOk,
117 },
118 "error on status": {
119 wantFail: true,
120 prepareMock: prepareMockErrOnStatus,
121 },
122 "empty response (no jails)": {
123 prepareMock: prepareMockEmptyResponse,
124 wantFail: true,
125 },
126 }
127
128 for name, test := range tests {
129 t.Run(name, func(t *testing.T) {
130 collr := New()
131 mock := test.prepareMock()
132 collr.exec = mock
133
134 if test.wantFail {
135 assert.Error(t, collr.Check(context.Background()))
136 } else {
137 assert.NoError(t, collr.Check(context.Background()))
138 }
139 })
140 }
141 }
142
143 func TestCollector_Collect(t *testing.T) {
144 tests := map[string]struct {
145 prepareMock func() *mockFail2BanClientCliExec
146 wantMetrics map[string]int64
147 }{
148 "success multiple jails": {
149 prepareMock: prepareMockOk,
150 wantMetrics: map[string]int64{
151 "jail_dovecot_currently_banned": 30,
152 "jail_dovecot_currently_failed": 10,
153 "jail_sshd_currently_banned": 30,
154 "jail_sshd_currently_failed": 10,
155 },
156 },
157 "error on status": {
158 prepareMock: prepareMockErrOnStatus,
159 wantMetrics: nil,
160 },
161 "empty response (no jails)": {
162 prepareMock: prepareMockEmptyResponse,
163 wantMetrics: nil,
164 },
165 }
166
167 for name, test := range tests {
168 t.Run(name, func(t *testing.T) {
169 collr := New()
170 mock := test.prepareMock()
171 collr.exec = mock
172
173 mx := collr.Collect(context.Background())
174
175 assert.Equal(t, test.wantMetrics, mx)
176
177 if len(test.wantMetrics) > 0 {
178 assert.Len(t, *collr.Charts(), len(jailChartsTmpl)*2, "wantCharts")
179
180 collecttest.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
181 }
182 })
183 }
184 }
185
186 func prepareMockOk() *mockFail2BanClientCliExec {
187 return &mockFail2BanClientCliExec{
188 statusData: dataStatus,
189 jailStatusData: dataJailStatus,
190 }
191 }
192
193 func prepareMockErrOnStatus() *mockFail2BanClientCliExec {
194 return &mockFail2BanClientCliExec{
195 errOnStatus: true,
196 statusData: dataStatus,
197 jailStatusData: dataJailStatus,
198 }
199 }
200
201 func prepareMockEmptyResponse() *mockFail2BanClientCliExec {
202 return &mockFail2BanClientCliExec{}
203 }
204
205 type mockFail2BanClientCliExec struct {
206 errOnStatus bool
207 statusData []byte
208
209 errOnJailStatus bool
210 jailStatusData []byte
211 }
212
213 func (m *mockFail2BanClientCliExec) status() ([]byte, error) {
214 if m.errOnStatus {
215 return nil, errors.New("mock.status() error")
216 }
217
218 return m.statusData, nil
219 }
220
221 func (m *mockFail2BanClientCliExec) jailStatus(_ string) ([]byte, error) {
222 if m.errOnJailStatus {
223 return nil, errors.New("mock.jailStatus() error")
224 }
225
226 return m.jailStatusData, nil
227 }