github.com/crowdsecurity/crowdsec@v1.6.1/pkg/acquisition/modules/syslog/syslog_test.go (about)

     1  package syslogacquisition
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"runtime"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/crowdsecurity/go-cs-lib/cstest"
    11  
    12  	"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
    13  	"github.com/crowdsecurity/crowdsec/pkg/types"
    14  	log "github.com/sirupsen/logrus"
    15  	"gopkg.in/tomb.v2"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  )
    19  
    20  func TestConfigure(t *testing.T) {
    21  	tests := []struct {
    22  		config      string
    23  		expectedErr string
    24  	}{
    25  		{
    26  			config: `
    27  foobar: bla
    28  source: syslog`,
    29  			expectedErr: "line 2: field foobar not found in type syslogacquisition.SyslogConfiguration",
    30  		},
    31  		{
    32  			config:      `source: syslog`,
    33  			expectedErr: "",
    34  		},
    35  		{
    36  			config: `
    37  source: syslog
    38  listen_port: asd`,
    39  			expectedErr: "cannot unmarshal !!str `asd` into int",
    40  		},
    41  		{
    42  			config: `
    43  source: syslog
    44  listen_port: 424242`,
    45  			expectedErr: "invalid port 424242",
    46  		},
    47  		{
    48  			config: `
    49  source: syslog
    50  listen_addr: 10.0.0`,
    51  			expectedErr: "invalid listen IP 10.0.0",
    52  		},
    53  	}
    54  
    55  	subLogger := log.WithFields(log.Fields{
    56  		"type": "syslog",
    57  	})
    58  	for _, test := range tests {
    59  		s := SyslogSource{}
    60  		err := s.Configure([]byte(test.config), subLogger, configuration.METRICS_NONE)
    61  		cstest.AssertErrorContains(t, err, test.expectedErr)
    62  	}
    63  }
    64  
    65  func writeToSyslog(logs []string) {
    66  	conn, err := net.Dial("udp", "127.0.0.1:4242")
    67  	if err != nil {
    68  		fmt.Printf("could not establish connection to syslog server : %s", err)
    69  		return
    70  	}
    71  	for _, log := range logs {
    72  		n, err := fmt.Fprint(conn, log)
    73  		if err != nil {
    74  			fmt.Printf("could not write to syslog server : %s", err)
    75  			return
    76  		}
    77  		if n != len(log) {
    78  			fmt.Printf("could not write to syslog server : %s", err)
    79  			return
    80  		}
    81  	}
    82  }
    83  
    84  func TestStreamingAcquisition(t *testing.T) {
    85  	tests := []struct {
    86  		name          string
    87  		config        string
    88  		expectedErr   string
    89  		logs          []string
    90  		expectedLines int
    91  	}{
    92  		{
    93  			name: "invalid msgs",
    94  			config: `source: syslog
    95  listen_port: 4242
    96  listen_addr: 127.0.0.1`,
    97  			logs: []string{"foobar", "bla", "pouet"},
    98  		},
    99  		{
   100  			name: "RFC5424",
   101  			config: `source: syslog
   102  listen_port: 4242
   103  listen_addr: 127.0.0.1`,
   104  			expectedLines: 2,
   105  			logs: []string{`<13>1 2021-05-18T11:58:40.828081+02:00 mantis sshd 49340 - [timeQuality isSynced="0" tzKnown="1"] blabla`,
   106  				`<13>1 2021-05-18T12:12:37.560695+02:00 mantis sshd 49340 - [timeQuality isSynced="0" tzKnown="1"] blabla2[foobar]`},
   107  		},
   108  		{
   109  			name: "RFC3164",
   110  			config: `source: syslog
   111  listen_port: 4242
   112  listen_addr: 127.0.0.1`,
   113  			expectedLines: 3,
   114  			logs: []string{`<13>May 18 12:37:56 mantis sshd[49340]: blabla2[foobar]`,
   115  				`<13>May 18 12:37:56 mantis sshd[49340]: blabla2`,
   116  				`<13>May 18 12:37:56 mantis sshd: blabla2`,
   117  				`<13>May 18 12:37:56 mantis sshd`},
   118  		},
   119  	}
   120  	if runtime.GOOS != "windows" {
   121  		tests = append(tests, struct {
   122  			name          string
   123  			config        string
   124  			expectedErr   string
   125  			logs          []string
   126  			expectedLines int
   127  		}{
   128  			name:        "privileged port",
   129  			config:      `source: syslog`,
   130  			expectedErr: "could not start syslog server: could not listen on port 514: listen udp 127.0.0.1:514: bind: permission denied",
   131  		})
   132  	}
   133  
   134  	for _, ts := range tests {
   135  		ts := ts
   136  		t.Run(ts.name, func(t *testing.T) {
   137  			subLogger := log.WithFields(log.Fields{
   138  				"type": "syslog",
   139  			})
   140  			s := SyslogSource{}
   141  			err := s.Configure([]byte(ts.config), subLogger, configuration.METRICS_NONE)
   142  			if err != nil {
   143  				t.Fatalf("could not configure syslog source : %s", err)
   144  			}
   145  			tomb := tomb.Tomb{}
   146  			out := make(chan types.Event)
   147  			err = s.StreamingAcquisition(out, &tomb)
   148  			cstest.AssertErrorContains(t, err, ts.expectedErr)
   149  			if ts.expectedErr != "" {
   150  				return
   151  			}
   152  			if err != nil && ts.expectedErr == "" {
   153  				t.Fatalf("unexpected error while starting syslog server: %s", err)
   154  				return
   155  			}
   156  
   157  			actualLines := 0
   158  			go writeToSyslog(ts.logs)
   159  		READLOOP:
   160  			for {
   161  				select {
   162  				case <-out:
   163  					actualLines++
   164  				case <-time.After(2 * time.Second):
   165  					break READLOOP
   166  				}
   167  			}
   168  			assert.Equal(t, ts.expectedLines, actualLines)
   169  			tomb.Kill(nil)
   170  			tomb.Wait()
   171  		})
   172  	}
   173  }