master
go 340 lines 9.27 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package samba
4
5 import (
6 "context"
7 "errors"
8 "os"
9 "testing"
10
11 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
12
13 "github.com/stretchr/testify/assert"
14 "github.com/stretchr/testify/require"
15 )
16
17 var (
18 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
19 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
20
21 dataSmbStatusProfile, _ = os.ReadFile("testdata/smbstatus-profile.txt")
22 )
23
24 func Test_testDataIsValid(t *testing.T) {
25 for name, data := range map[string][]byte{
26 "dataConfigJSON": dataConfigJSON,
27 "dataConfigYAML": dataConfigYAML,
28 "dataSmbStatusProfile": dataSmbStatusProfile,
29 } {
30 require.NotNil(t, data, name)
31
32 }
33 }
34
35 func TestCollector_Configuration(t *testing.T) {
36 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
37 }
38
39 func TestCollector_Init(t *testing.T) {
40 tests := map[string]struct {
41 config Config
42 wantFail bool
43 }{
44 "success with default config": {
45 wantFail: false,
46 config: New().Config,
47 },
48 }
49
50 for name, test := range tests {
51 t.Run(name, func(t *testing.T) {
52 collr := New()
53 collr.Config = test.config
54
55 if test.wantFail {
56 assert.Error(t, collr.Init(context.Background()))
57 } else {
58 assert.NoError(t, collr.Init(context.Background()))
59 }
60 })
61 }
62 }
63
64 func TestCollector_Cleanup(t *testing.T) {
65 tests := map[string]struct {
66 prepare func() *Collector
67 }{
68 "not initialized exec": {
69 prepare: func() *Collector {
70 return New()
71 },
72 },
73 "after check": {
74 prepare: func() *Collector {
75 collr := New()
76 collr.exec = prepareMockOk()
77 _ = collr.Check(context.Background())
78 return collr
79 },
80 },
81 "after collect": {
82 prepare: func() *Collector {
83 collr := New()
84 collr.exec = prepareMockOk()
85 _ = collr.Collect(context.Background())
86 return collr
87 },
88 },
89 }
90
91 for name, test := range tests {
92 t.Run(name, func(t *testing.T) {
93 collr := test.prepare()
94
95 assert.NotPanics(t, func() { collr.Cleanup(context.Background()) })
96 })
97 }
98 }
99
100 func TestCollectorCharts(t *testing.T) {
101 assert.NotNil(t, New().Charts())
102 }
103
104 func TestCollector_Check(t *testing.T) {
105 tests := map[string]struct {
106 prepareMock func() *mockSmbStatusBinary
107 wantFail bool
108 }{
109 "success case": {
110 prepareMock: prepareMockOk,
111 wantFail: false,
112 },
113 "error on exec": {
114 prepareMock: prepareMockErr,
115 wantFail: true,
116 },
117 "empty response": {
118 prepareMock: prepareMockEmptyResponse,
119 wantFail: true,
120 },
121 "unexpected response": {
122 prepareMock: prepareMockUnexpectedResponse,
123 wantFail: true,
124 },
125 }
126
127 for name, test := range tests {
128 t.Run(name, func(t *testing.T) {
129 collr := New()
130 mock := test.prepareMock()
131 collr.exec = mock
132
133 if test.wantFail {
134 assert.Error(t, collr.Check(context.Background()))
135 } else {
136 assert.NoError(t, collr.Check(context.Background()))
137 }
138 })
139 }
140 }
141
142 func TestCollector_Collect(t *testing.T) {
143 tests := map[string]struct {
144 prepareMock func() *mockSmbStatusBinary
145 wantMetrics map[string]int64
146 wantCharts int
147 }{
148 "success case": {
149 prepareMock: prepareMockOk,
150 wantCharts: 53 /*syscall count*/ + 8 /*syscall bytes*/ + (19 * 2), /*smb2calls count and bytes*/
151 wantMetrics: map[string]int64{
152 "smb2_break_count": 0,
153 "smb2_break_inbytes": 0,
154 "smb2_break_outbytes": 0,
155 "smb2_cancel_count": 0,
156 "smb2_cancel_inbytes": 0,
157 "smb2_cancel_outbytes": 0,
158 "smb2_close_count": 0,
159 "smb2_close_inbytes": 0,
160 "smb2_close_outbytes": 0,
161 "smb2_create_count": 0,
162 "smb2_create_inbytes": 0,
163 "smb2_create_outbytes": 0,
164 "smb2_find_count": 0,
165 "smb2_find_inbytes": 0,
166 "smb2_find_outbytes": 0,
167 "smb2_flush_count": 0,
168 "smb2_flush_inbytes": 0,
169 "smb2_flush_outbytes": 0,
170 "smb2_getinfo_count": 0,
171 "smb2_getinfo_inbytes": 0,
172 "smb2_getinfo_outbytes": 0,
173 "smb2_ioctl_count": 0,
174 "smb2_ioctl_inbytes": 0,
175 "smb2_ioctl_outbytes": 0,
176 "smb2_keepalive_count": 0,
177 "smb2_keepalive_inbytes": 0,
178 "smb2_keepalive_outbytes": 0,
179 "smb2_lock_count": 0,
180 "smb2_lock_inbytes": 0,
181 "smb2_lock_outbytes": 0,
182 "smb2_logoff_count": 0,
183 "smb2_logoff_inbytes": 0,
184 "smb2_logoff_outbytes": 0,
185 "smb2_negprot_count": 0,
186 "smb2_negprot_inbytes": 0,
187 "smb2_negprot_outbytes": 0,
188 "smb2_notify_count": 0,
189 "smb2_notify_inbytes": 0,
190 "smb2_notify_outbytes": 0,
191 "smb2_read_count": 0,
192 "smb2_read_inbytes": 0,
193 "smb2_read_outbytes": 0,
194 "smb2_sesssetup_count": 0,
195 "smb2_sesssetup_inbytes": 0,
196 "smb2_sesssetup_outbytes": 0,
197 "smb2_setinfo_count": 0,
198 "smb2_setinfo_inbytes": 0,
199 "smb2_setinfo_outbytes": 0,
200 "smb2_tcon_count": 0,
201 "smb2_tcon_inbytes": 0,
202 "smb2_tcon_outbytes": 0,
203 "smb2_tdis_count": 0,
204 "smb2_tdis_inbytes": 0,
205 "smb2_tdis_outbytes": 0,
206 "smb2_write_count": 0,
207 "smb2_write_inbytes": 0,
208 "smb2_write_outbytes": 0,
209 "syscall_asys_fsync_bytes": 0,
210 "syscall_asys_fsync_count": 0,
211 "syscall_asys_getxattrat_bytes": 0,
212 "syscall_asys_getxattrat_count": 0,
213 "syscall_asys_pread_bytes": 0,
214 "syscall_asys_pread_count": 0,
215 "syscall_asys_pwrite_bytes": 0,
216 "syscall_asys_pwrite_count": 0,
217 "syscall_brl_cancel_count": 0,
218 "syscall_brl_lock_count": 0,
219 "syscall_brl_unlock_count": 0,
220 "syscall_chdir_count": 0,
221 "syscall_chmod_count": 0,
222 "syscall_close_count": 0,
223 "syscall_closedir_count": 0,
224 "syscall_createfile_count": 0,
225 "syscall_fallocate_count": 0,
226 "syscall_fchmod_count": 0,
227 "syscall_fchown_count": 0,
228 "syscall_fcntl_count": 0,
229 "syscall_fcntl_getlock_count": 0,
230 "syscall_fcntl_lock_count": 0,
231 "syscall_fdopendir_count": 0,
232 "syscall_fntimes_count": 0,
233 "syscall_fstat_count": 0,
234 "syscall_fstatat_count": 0,
235 "syscall_ftruncate_count": 0,
236 "syscall_get_alloc_size_count": 0,
237 "syscall_get_quota_count": 0,
238 "syscall_get_sd_count": 0,
239 "syscall_getwd_count": 0,
240 "syscall_lchown_count": 0,
241 "syscall_linkat_count": 0,
242 "syscall_linux_setlease_count": 0,
243 "syscall_lseek_count": 0,
244 "syscall_lstat_count": 0,
245 "syscall_mkdirat_count": 0,
246 "syscall_mknodat_count": 0,
247 "syscall_open_count": 0,
248 "syscall_openat_count": 0,
249 "syscall_opendir_count": 0,
250 "syscall_pread_bytes": 0,
251 "syscall_pread_count": 0,
252 "syscall_pwrite_bytes": 0,
253 "syscall_pwrite_count": 0,
254 "syscall_readdir_count": 0,
255 "syscall_readlinkat_count": 0,
256 "syscall_realpath_count": 0,
257 "syscall_recvfile_bytes": 0,
258 "syscall_recvfile_count": 0,
259 "syscall_renameat_count": 0,
260 "syscall_rewinddir_count": 0,
261 "syscall_seekdir_count": 0,
262 "syscall_sendfile_bytes": 0,
263 "syscall_sendfile_count": 0,
264 "syscall_set_quota_count": 0,
265 "syscall_set_sd_count": 0,
266 "syscall_stat_count": 0,
267 "syscall_symlinkat_count": 0,
268 "syscall_telldir_count": 0,
269 "syscall_unlinkat_count": 0,
270 },
271 },
272 "error on exec": {
273 prepareMock: prepareMockErr,
274 wantMetrics: nil,
275 },
276 "empty response": {
277 prepareMock: prepareMockEmptyResponse,
278 wantMetrics: nil,
279 },
280 "unexpected response": {
281 prepareMock: prepareMockUnexpectedResponse,
282 wantMetrics: nil,
283 },
284 }
285
286 for name, test := range tests {
287 t.Run(name, func(t *testing.T) {
288 collr := New()
289 mock := test.prepareMock()
290 collr.exec = mock
291
292 mx := collr.Collect(context.Background())
293
294 assert.Equal(t, test.wantMetrics, mx)
295
296 if len(test.wantMetrics) > 0 {
297 assert.Len(t, *collr.Charts(), test.wantCharts, "want charts")
298 collecttest.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
299 }
300 })
301 }
302 }
303
304 func prepareMockOk() *mockSmbStatusBinary {
305 return &mockSmbStatusBinary{
306 data: dataSmbStatusProfile,
307 }
308 }
309
310 func prepareMockErr() *mockSmbStatusBinary {
311 return &mockSmbStatusBinary{
312 err: true,
313 }
314 }
315
316 func prepareMockEmptyResponse() *mockSmbStatusBinary {
317 return &mockSmbStatusBinary{}
318 }
319
320 func prepareMockUnexpectedResponse() *mockSmbStatusBinary {
321 return &mockSmbStatusBinary{
322 data: []byte(`
323 Lorem ipsum dolor sit amet, consectetur adipiscing elit.
324 Nulla malesuada erat id magna mattis, eu viverra tellus rhoncus.
325 Fusce et felis pulvinar, posuere sem non, porttitor eros.
326 `),
327 }
328 }
329
330 type mockSmbStatusBinary struct {
331 err bool
332 data []byte
333 }
334
335 func (m *mockSmbStatusBinary) profile() ([]byte, error) {
336 if m.err {
337 return nil, errors.New("mock.profile() error")
338 }
339 return m.data, nil
340 }