github.com/netdata/go.d.plugin@v0.58.1/modules/filecheck/filecheck_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package filecheck 4 5 import ( 6 "strings" 7 "testing" 8 9 "github.com/netdata/go.d.plugin/agent/module" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestNew(t *testing.T) { 16 assert.Implements(t, (*module.Module)(nil), New()) 17 } 18 19 func TestFilecheck_Cleanup(t *testing.T) { 20 assert.NotPanics(t, New().Cleanup) 21 } 22 23 func TestFilecheck_Init(t *testing.T) { 24 tests := map[string]struct { 25 config Config 26 wantNumOfCharts int 27 wantFail bool 28 }{ 29 "default": { 30 config: New().Config, 31 wantFail: true, 32 }, 33 "empty files->include and dirs->include": { 34 config: Config{ 35 Files: filesConfig{}, 36 Dirs: dirsConfig{}, 37 }, 38 wantFail: true, 39 }, 40 "files->include and dirs->include": { 41 config: Config{ 42 Files: filesConfig{ 43 Include: []string{ 44 "/path/to/file1", 45 "/path/to/file2", 46 }, 47 }, 48 Dirs: dirsConfig{ 49 Include: []string{ 50 "/path/to/dir1", 51 "/path/to/dir2", 52 }, 53 CollectDirSize: true, 54 }, 55 }, 56 wantNumOfCharts: len(fileCharts) + len(dirCharts), 57 }, 58 "only files->include": { 59 config: Config{ 60 Files: filesConfig{ 61 Include: []string{ 62 "/path/to/file1", 63 "/path/to/file2", 64 }, 65 }, 66 }, 67 wantNumOfCharts: len(fileCharts), 68 }, 69 "only dirs->include": { 70 config: Config{ 71 Dirs: dirsConfig{ 72 Include: []string{ 73 "/path/to/dir1", 74 "/path/to/dir2", 75 }, 76 CollectDirSize: true, 77 }, 78 }, 79 wantNumOfCharts: len(dirCharts), 80 }, 81 } 82 83 for name, test := range tests { 84 t.Run(name, func(t *testing.T) { 85 fc := New() 86 fc.Config = test.config 87 88 if test.wantFail { 89 assert.False(t, fc.Init()) 90 } else { 91 require.True(t, fc.Init()) 92 assert.Equal(t, test.wantNumOfCharts, len(*fc.Charts())) 93 } 94 }) 95 } 96 } 97 98 func TestFilecheck_Check(t *testing.T) { 99 tests := map[string]struct { 100 prepare func() *Filecheck 101 }{ 102 "collect files": {prepare: prepareFilecheckFiles}, 103 "collect files filepath pattern": {prepare: prepareFilecheckGlobFiles}, 104 "collect only non existent files": {prepare: prepareFilecheckNonExistentFiles}, 105 "collect dirs": {prepare: prepareFilecheckDirs}, 106 "collect dirs filepath pattern": {prepare: prepareFilecheckGlobDirs}, 107 "collect only non existent dirs": {prepare: prepareFilecheckNonExistentDirs}, 108 "collect files and dirs": {prepare: prepareFilecheckFilesDirs}, 109 } 110 111 for name, test := range tests { 112 t.Run(name, func(t *testing.T) { 113 fc := test.prepare() 114 require.True(t, fc.Init()) 115 116 assert.True(t, fc.Check()) 117 }) 118 } 119 } 120 121 func TestFilecheck_Collect(t *testing.T) { 122 // TODO: should use TEMP dir and create files/dirs dynamically during a test case 123 tests := map[string]struct { 124 prepare func() *Filecheck 125 wantCollected map[string]int64 126 }{ 127 "collect files": { 128 prepare: prepareFilecheckFiles, 129 wantCollected: map[string]int64{ 130 "file_testdata/empty_file.log_exists": 1, 131 "file_testdata/empty_file.log_mtime_ago": 5081, 132 "file_testdata/empty_file.log_size_bytes": 0, 133 "file_testdata/file.log_exists": 1, 134 "file_testdata/file.log_mtime_ago": 4161, 135 "file_testdata/file.log_size_bytes": 5707, 136 "file_testdata/non_existent_file.log_exists": 0, 137 "num_of_files": 3, 138 "num_of_dirs": 0, 139 }, 140 }, 141 "collect files filepath pattern": { 142 prepare: prepareFilecheckGlobFiles, 143 wantCollected: map[string]int64{ 144 "file_testdata/empty_file.log_exists": 1, 145 "file_testdata/empty_file.log_mtime_ago": 5081, 146 "file_testdata/empty_file.log_size_bytes": 0, 147 "file_testdata/file.log_exists": 1, 148 "file_testdata/file.log_mtime_ago": 4161, 149 "file_testdata/file.log_size_bytes": 5707, 150 "num_of_files": 2, 151 "num_of_dirs": 0, 152 }, 153 }, 154 "collect only non existent files": { 155 prepare: prepareFilecheckNonExistentFiles, 156 wantCollected: map[string]int64{ 157 "file_testdata/non_existent_file.log_exists": 0, 158 "num_of_files": 1, 159 "num_of_dirs": 0, 160 }, 161 }, 162 "collect dirs": { 163 prepare: prepareFilecheckDirs, 164 wantCollected: map[string]int64{ 165 "dir_testdata/dir_exists": 1, 166 "dir_testdata/dir_mtime_ago": 4087, 167 "dir_testdata/dir_num_of_files": 3, 168 "dir_testdata/dir_size_bytes": 8160, 169 "dir_testdata/non_existent_dir_exists": 0, 170 "num_of_files": 0, 171 "num_of_dirs": 2, 172 }, 173 }, 174 "collect dirs filepath pattern": { 175 prepare: prepareFilecheckGlobDirs, 176 wantCollected: map[string]int64{ 177 "dir_testdata/dir_exists": 1, 178 "dir_testdata/dir_mtime_ago": 4087, 179 "dir_testdata/dir_num_of_files": 3, 180 "dir_testdata/dir_size_bytes": 8160, 181 "dir_testdata/non_existent_dir_exists": 0, 182 "num_of_files": 0, 183 "num_of_dirs": 2, 184 }, 185 }, 186 "collect dirs w/o size": { 187 prepare: prepareFilecheckDirsWithoutSize, 188 wantCollected: map[string]int64{ 189 "dir_testdata/dir_exists": 1, 190 "dir_testdata/dir_mtime_ago": 4087, 191 "dir_testdata/dir_num_of_files": 3, 192 "dir_testdata/non_existent_dir_exists": 0, 193 "num_of_files": 0, 194 "num_of_dirs": 2, 195 }, 196 }, 197 "collect only non existent dirs": { 198 prepare: prepareFilecheckNonExistentDirs, 199 wantCollected: map[string]int64{ 200 "dir_testdata/non_existent_dir_exists": 0, 201 "num_of_files": 0, 202 "num_of_dirs": 1, 203 }, 204 }, 205 "collect files and dirs": { 206 prepare: prepareFilecheckFilesDirs, 207 wantCollected: map[string]int64{ 208 "dir_testdata/dir_exists": 1, 209 "dir_testdata/dir_mtime_ago": 4120, 210 "dir_testdata/dir_num_of_files": 3, 211 "dir_testdata/dir_size_bytes": 8160, 212 "dir_testdata/non_existent_dir_exists": 0, 213 "file_testdata/empty_file.log_exists": 1, 214 "file_testdata/empty_file.log_mtime_ago": 5176, 215 "file_testdata/empty_file.log_size_bytes": 0, 216 "file_testdata/file.log_exists": 1, 217 "file_testdata/file.log_mtime_ago": 4256, 218 "file_testdata/file.log_size_bytes": 5707, 219 "file_testdata/non_existent_file.log_exists": 0, 220 "num_of_files": 3, 221 "num_of_dirs": 2, 222 }, 223 }, 224 } 225 226 for name, test := range tests { 227 t.Run(name, func(t *testing.T) { 228 fc := test.prepare() 229 require.True(t, fc.Init()) 230 231 collected := fc.Collect() 232 233 copyModTime(test.wantCollected, collected) 234 assert.Equal(t, test.wantCollected, collected) 235 ensureCollectedHasAllChartsDimsVarsIDs(t, fc, collected) 236 }) 237 } 238 } 239 240 func ensureCollectedHasAllChartsDimsVarsIDs(t *testing.T, fc *Filecheck, collected map[string]int64) { 241 // TODO: check other charts 242 for _, chart := range *fc.Charts() { 243 if chart.Obsolete { 244 continue 245 } 246 switch chart.ID { 247 case fileExistenceChart.ID, dirExistenceChart.ID: 248 for _, dim := range chart.Dims { 249 _, ok := collected[dim.ID] 250 assert.Truef(t, ok, "collected metrics has no data for dim '%s' chart '%s'", dim.ID, chart.ID) 251 } 252 for _, v := range chart.Vars { 253 _, ok := collected[v.ID] 254 assert.Truef(t, ok, "collected metrics has no data for var '%s' chart '%s'", v.ID, chart.ID) 255 } 256 } 257 } 258 } 259 260 func prepareFilecheckFiles() *Filecheck { 261 fc := New() 262 fc.Config.Files.Include = []string{ 263 "testdata/empty_file.log", 264 "testdata/file.log", 265 "testdata/non_existent_file.log", 266 } 267 return fc 268 } 269 270 func prepareFilecheckGlobFiles() *Filecheck { 271 fc := New() 272 fc.Config.Files.Include = []string{ 273 "testdata/*.log", 274 } 275 return fc 276 } 277 278 func prepareFilecheckNonExistentFiles() *Filecheck { 279 fc := New() 280 fc.Config.Files.Include = []string{ 281 "testdata/non_existent_file.log", 282 } 283 return fc 284 } 285 286 func prepareFilecheckDirs() *Filecheck { 287 fc := New() 288 fc.Config.Dirs.Include = []string{ 289 "testdata/dir", 290 "testdata/non_existent_dir", 291 } 292 return fc 293 } 294 295 func prepareFilecheckGlobDirs() *Filecheck { 296 fc := New() 297 fc.Config.Dirs.Include = []string{ 298 "testdata/*ir", 299 "testdata/non_existent_dir", 300 } 301 return fc 302 } 303 304 func prepareFilecheckDirsWithoutSize() *Filecheck { 305 fc := New() 306 fc.Config.Dirs.Include = []string{ 307 "testdata/dir", 308 "testdata/non_existent_dir", 309 } 310 fc.Config.Dirs.CollectDirSize = false 311 return fc 312 } 313 314 func prepareFilecheckNonExistentDirs() *Filecheck { 315 fc := New() 316 fc.Config.Dirs.Include = []string{ 317 "testdata/non_existent_dir", 318 } 319 return fc 320 } 321 322 func prepareFilecheckFilesDirs() *Filecheck { 323 fc := New() 324 fc.Config.Files.Include = []string{ 325 "testdata/empty_file.log", 326 "testdata/file.log", 327 "testdata/non_existent_file.log", 328 } 329 fc.Config.Dirs.Include = []string{ 330 "testdata/dir", 331 "testdata/non_existent_dir", 332 } 333 return fc 334 } 335 336 func copyModTime(dst, src map[string]int64) { 337 if src == nil || dst == nil { 338 return 339 } 340 for key := range src { 341 if strings.Contains(key, "mtime") { 342 dst[key] = src[key] 343 } 344 } 345 }