bitbucket.org/Aishee/synsec@v0.0.0-20210414005726-236fc01a153d/pkg/exprhelpers/exprlib_test.go (about) 1 package exprhelpers 2 3 import ( 4 "fmt" 5 6 log "github.com/sirupsen/logrus" 7 8 "testing" 9 10 "github.com/antonmedv/expr" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 var ( 16 TestFolder = "tests" 17 ) 18 19 func TestVisitor(t *testing.T) { 20 if err := Init(); err != nil { 21 log.Fatalf(err.Error()) 22 } 23 24 tests := []struct { 25 name string 26 filter string 27 result bool 28 env map[string]interface{} 29 err error 30 }{ 31 { 32 name: "debug : no variable", 33 filter: "'synsec' startsWith 'crowdse'", 34 result: true, 35 err: nil, 36 env: map[string]interface{}{}, 37 }, 38 { 39 name: "debug : simple variable", 40 filter: "'synsec' startsWith static_one && 1 == 1", 41 result: true, 42 err: nil, 43 env: map[string]interface{}{"static_one": string("crowdse")}, 44 }, 45 { 46 name: "debug : simple variable re-used", 47 filter: "static_one.foo == 'bar' && static_one.foo != 'toto'", 48 result: true, 49 err: nil, 50 env: map[string]interface{}{"static_one": map[string]string{"foo": "bar"}}, 51 }, 52 { 53 name: "debug : can't compile", 54 filter: "static_one.foo.toto == 'lol'", 55 result: false, 56 err: fmt.Errorf("bad syntax"), 57 env: map[string]interface{}{"static_one": map[string]string{"foo": "bar"}}, 58 }, 59 { 60 name: "debug : can't compile #2", 61 filter: "static_one.f!oo.to/to == 'lol'", 62 result: false, 63 err: fmt.Errorf("bad syntax"), 64 env: map[string]interface{}{"static_one": map[string]string{"foo": "bar"}}, 65 }, 66 { 67 name: "debug : can't compile #3", 68 filter: "", 69 result: false, 70 err: fmt.Errorf("bad syntax"), 71 env: map[string]interface{}{"static_one": map[string]string{"foo": "bar"}}, 72 }, 73 } 74 75 log.SetLevel(log.DebugLevel) 76 clog := log.WithFields(log.Fields{ 77 "type": "test", 78 }) 79 80 for _, test := range tests { 81 compiledFilter, err := expr.Compile(test.filter, expr.Env(GetExprEnv(test.env))) 82 if err != nil && test.err == nil { 83 log.Fatalf("compile: %s", err.Error()) 84 } 85 debugFilter, err := NewDebugger(test.filter, expr.Env(GetExprEnv(test.env))) 86 if err != nil && test.err == nil { 87 log.Fatalf("debug: %s", err.Error()) 88 } 89 90 if compiledFilter != nil { 91 result, err := expr.Run(compiledFilter, GetExprEnv(test.env)) 92 if err != nil && test.err == nil { 93 log.Fatalf("run : %s", err.Error()) 94 } 95 if isOk := assert.Equal(t, test.result, result); !isOk { 96 t.Fatalf("test '%s' : NOK", test.filter) 97 } 98 } 99 100 if debugFilter != nil { 101 debugFilter.Run(clog, test.result, GetExprEnv(test.env)) 102 } 103 } 104 } 105 106 func TestRegexpInFile(t *testing.T) { 107 if err := Init(); err != nil { 108 log.Fatalf(err.Error()) 109 } 110 111 err := FileInit(TestFolder, "test_data_re.txt", "regex") 112 if err != nil { 113 log.Fatalf(err.Error()) 114 } 115 116 tests := []struct { 117 name string 118 filter string 119 result bool 120 err error 121 }{ 122 { 123 name: "RegexpInFile() test: lower case word in data file", 124 filter: "RegexpInFile('synsec', 'test_data_re.txt')", 125 result: false, 126 err: nil, 127 }, 128 { 129 name: "RegexpInFile() test: Match exactly", 130 filter: "RegexpInFile('Synsec', 'test_data_re.txt')", 131 result: true, 132 err: nil, 133 }, 134 { 135 name: "RegexpInFile() test: match with word before", 136 filter: "RegexpInFile('test Synsec', 'test_data_re.txt')", 137 result: true, 138 err: nil, 139 }, 140 { 141 name: "RegexpInFile() test: match with word before and other case", 142 filter: "RegexpInFile('test SynSec', 'test_data_re.txt')", 143 result: true, 144 err: nil, 145 }, 146 } 147 148 for _, test := range tests { 149 compiledFilter, err := expr.Compile(test.filter, expr.Env(GetExprEnv(map[string]interface{}{}))) 150 if err != nil { 151 log.Fatalf(err.Error()) 152 } 153 result, err := expr.Run(compiledFilter, GetExprEnv(map[string]interface{}{})) 154 if err != nil { 155 log.Fatalf(err.Error()) 156 } 157 if isOk := assert.Equal(t, test.result, result); !isOk { 158 t.Fatalf("test '%s' : NOK", test.name) 159 } 160 } 161 } 162 163 func TestFileInit(t *testing.T) { 164 if err := Init(); err != nil { 165 log.Fatalf(err.Error()) 166 } 167 168 tests := []struct { 169 name string 170 filename string 171 types string 172 result int 173 err error 174 }{ 175 { 176 name: "file with type:string", 177 filename: "test_data.txt", 178 types: "string", 179 result: 3, 180 }, 181 { 182 name: "file with type:string and empty lines + commentaries", 183 filename: "test_empty_line.txt", 184 types: "string", 185 result: 3, 186 }, 187 { 188 name: "file with type:re", 189 filename: "test_data_re.txt", 190 types: "regex", 191 result: 2, 192 }, 193 { 194 name: "file without type", 195 filename: "test_data_no_type.txt", 196 types: "", 197 }, 198 } 199 200 for _, test := range tests { 201 err := FileInit(TestFolder, test.filename, test.types) 202 if err != nil { 203 log.Fatalf(err.Error()) 204 } 205 if test.types == "string" { 206 if _, ok := dataFile[test.filename]; !ok { 207 t.Fatalf("test '%s' : NOK", test.name) 208 } 209 if isOk := assert.Equal(t, test.result, len(dataFile[test.filename])); !isOk { 210 t.Fatalf("test '%s' : NOK", test.name) 211 } 212 } else if test.types == "regex" { 213 if _, ok := dataFileRegex[test.filename]; !ok { 214 t.Fatalf("test '%s' : NOK", test.name) 215 } 216 if isOk := assert.Equal(t, test.result, len(dataFileRegex[test.filename])); !isOk { 217 t.Fatalf("test '%s' : NOK", test.name) 218 } 219 } else { 220 if _, ok := dataFileRegex[test.filename]; ok { 221 t.Fatalf("test '%s' : NOK", test.name) 222 } 223 if _, ok := dataFile[test.filename]; ok { 224 t.Fatalf("test '%s' : NOK", test.name) 225 } 226 } 227 log.Printf("test '%s' : OK", test.name) 228 } 229 } 230 231 func TestFile(t *testing.T) { 232 if err := Init(); err != nil { 233 log.Fatalf(err.Error()) 234 } 235 236 err := FileInit(TestFolder, "test_data.txt", "string") 237 if err != nil { 238 log.Fatalf(err.Error()) 239 } 240 241 tests := []struct { 242 name string 243 filter string 244 result bool 245 err error 246 }{ 247 { 248 name: "File() test: word in file", 249 filter: "'Synsec' in File('test_data.txt')", 250 result: true, 251 err: nil, 252 }, 253 { 254 name: "File() test: word in file but different case", 255 filter: "'BreakTeam' in File('test_data.txt')", 256 result: false, 257 err: nil, 258 }, 259 { 260 name: "File() test: word not in file", 261 filter: "'test' in File('test_data.txt')", 262 result: false, 263 err: nil, 264 }, 265 { 266 name: "File() test: filepath provided doesn't exist", 267 filter: "'test' in File('non_existing_data.txt')", 268 result: false, 269 err: nil, 270 }, 271 } 272 273 for _, test := range tests { 274 compiledFilter, err := expr.Compile(test.filter, expr.Env(GetExprEnv(map[string]interface{}{}))) 275 if err != nil { 276 log.Fatalf(err.Error()) 277 } 278 result, err := expr.Run(compiledFilter, GetExprEnv(map[string]interface{}{})) 279 if err != nil { 280 log.Fatalf(err.Error()) 281 } 282 if isOk := assert.Equal(t, test.result, result); !isOk { 283 t.Fatalf("test '%s' : NOK", test.name) 284 } 285 log.Printf("test '%s' : OK", test.name) 286 287 } 288 } 289 290 func TestIpInRange(t *testing.T) { 291 tests := []struct { 292 name string 293 env map[string]interface{} 294 code string 295 result bool 296 err string 297 }{ 298 { 299 name: "IpInRange() test: basic test", 300 env: map[string]interface{}{ 301 "ip": "192.168.0.1", 302 "ipRange": "192.168.0.0/24", 303 "IpInRange": IpInRange, 304 }, 305 code: "IpInRange(ip, ipRange)", 306 result: true, 307 err: "", 308 }, 309 { 310 name: "IpInRange() test: malformed IP", 311 env: map[string]interface{}{ 312 "ip": "192.168.0", 313 "ipRange": "192.168.0.0/24", 314 "IpInRange": IpInRange, 315 }, 316 code: "IpInRange(ip, ipRange)", 317 result: false, 318 err: "", 319 }, 320 { 321 name: "IpInRange() test: malformed IP range", 322 env: map[string]interface{}{ 323 "ip": "192.168.0.0/255", 324 "ipRange": "192.168.0.0/24", 325 "IpInRange": IpInRange, 326 }, 327 code: "IpInRange(ip, ipRange)", 328 result: false, 329 err: "", 330 }, 331 } 332 333 for _, test := range tests { 334 program, err := expr.Compile(test.code, expr.Env(test.env)) 335 require.NoError(t, err) 336 output, err := expr.Run(program, test.env) 337 require.NoError(t, err) 338 require.Equal(t, test.result, output) 339 log.Printf("test '%s' : OK", test.name) 340 } 341 342 } 343 344 func TestAtof(t *testing.T) { 345 testFloat := "1.5" 346 expectedFloat := 1.5 347 348 if Atof(testFloat) != expectedFloat { 349 t.Fatalf("Atof should returned 1.5 as a float") 350 } 351 352 log.Printf("test 'Atof()' : OK") 353 354 //bad float 355 testFloat = "1aaa.5" 356 expectedFloat = 0.0 357 358 if Atof(testFloat) != expectedFloat { 359 t.Fatalf("Atof should returned a negative value (error) as a float got") 360 } 361 362 log.Printf("test 'Atof()' : OK") 363 } 364 365 func TestUpper(t *testing.T) { 366 testStr := "test" 367 expectedStr := "TEST" 368 369 if Upper(testStr) != expectedStr { 370 t.Fatalf("Upper() should returned 1.5 as a float") 371 } 372 373 log.Printf("test 'Upper()' : OK") 374 }