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  }