浏览代码

refactor broker_test.go, extract cstest/filenotfound*.go (#1815)

mmetc 2 年之前
父节点
当前提交
ec0d2a5ed2

+ 8 - 17
pkg/acquisition/acquisition_test.go

@@ -6,16 +6,17 @@ import (
 	"testing"
 	"time"
 
-	"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
-	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
-	"github.com/crowdsecurity/crowdsec/pkg/cstest"
-	"github.com/crowdsecurity/crowdsec/pkg/types"
 	"github.com/pkg/errors"
 	"github.com/prometheus/client_golang/prometheus"
 	log "github.com/sirupsen/logrus"
 	tomb "gopkg.in/tomb.v2"
 	"gopkg.in/yaml.v2"
 	"gotest.tools/v3/assert"
+
+	"github.com/crowdsecurity/crowdsec/pkg/acquisition/configuration"
+	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
+	"github.com/crowdsecurity/crowdsec/pkg/cstest"
+	"github.com/crowdsecurity/crowdsec/pkg/types"
 )
 
 type MockSource struct {
@@ -226,7 +227,7 @@ func TestLoadAcquisitionFromFile(t *testing.T) {
 			Config: csconfig.CrowdsecServiceCfg{
 				AcquisitionFiles: []string{"does_not_exist"},
 			},
-			ExpectedError: "can't open does_not_exist",
+			ExpectedError: cstest.FileNotFoundMessage,
 			ExpectedLen:   0,
 		},
 		{
@@ -282,18 +283,8 @@ func TestLoadAcquisitionFromFile(t *testing.T) {
 	}
 	for _, test := range tests {
 		dss, err := LoadAcquisitionFromFile(&test.Config)
-		if test.ExpectedError != "" {
-			if err == nil {
-				t.Fatalf("expected error %s, got none", test.ExpectedError)
-			}
-			if !strings.Contains(err.Error(), test.ExpectedError) {
-				t.Fatalf("%s : expected error '%s' in '%s'", test.TestName, test.ExpectedError, err)
-			}
-			continue
-		}
-		if err != nil {
-			t.Fatalf("%s : unexpected error '%s'", test.TestName, err)
-		}
+		cstest.RequireErrorContains(t, err, test.ExpectedError)
+
 		if len(dss) != test.ExpectedLen {
 			t.Fatalf("%s : expected %d datasources got %d", test.TestName, test.ExpectedLen, len(dss))
 		}

+ 13 - 26
pkg/csconfig/config_test.go

@@ -1,27 +1,20 @@
 package csconfig
 
 import (
-	"fmt"
-	"log"
-	"runtime"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	"github.com/crowdsecurity/crowdsec/pkg/cstest"
 )
 
 func TestNormalLoad(t *testing.T) {
-
 	_, err := NewConfig("./tests/config.yaml", false, false)
-	if err != nil {
-		t.Fatalf("unexpected error %s", err)
-	}
+	require.NoError(t, err)
 
 	_, err = NewConfig("./tests/xxx.yaml", false, false)
-	if runtime.GOOS != "windows" {
-		assert.EqualError(t, err, "while reading yaml file: open ./tests/xxx.yaml: no such file or directory")
-	} else {
-		assert.EqualError(t, err, "while reading yaml file: open ./tests/xxx.yaml: The system cannot find the file specified.")
-	}
+	assert.EqualError(t, err, "while reading yaml file: open ./tests/xxx.yaml: "+cstest.FileNotFoundMessage)
 
 	_, err = NewConfig("./tests/simulation.yaml", false, false)
 	assert.EqualError(t, err, "./tests/simulation.yaml: yaml: unmarshal errors:\n  line 1: field simulation not found in type csconfig.Config")
@@ -31,29 +24,23 @@ func TestNewCrowdSecConfig(t *testing.T) {
 	tests := []struct {
 		name           string
 		expectedResult *Config
-		err            string
 	}{
 		{
 			name:           "new configuration: basic",
 			expectedResult: &Config{},
-			err:            "",
 		},
 	}
-	for _, test := range tests {
-		result := &Config{}
-		isOk := assert.Equal(t, test.expectedResult, result)
-		if !isOk {
-			t.Fatalf("TEST '%s': NOK", test.name)
-		} else {
-			fmt.Printf("TEST '%s': OK\n", test.name)
-		}
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			result := &Config{}
+			assert.Equal(t, tc.expectedResult, result)
+		})
 	}
-
 }
 
 func TestDefaultConfig(t *testing.T) {
 	x := NewDefaultConfig()
-	if err := x.Dump(); err != nil {
-		log.Fatal(err)
-	}
+	err := x.Dump()
+	require.NoError(t, err)
 }

+ 30 - 73
pkg/csconfig/simulation_test.go

@@ -3,30 +3,26 @@ package csconfig
 import (
 	"fmt"
 	"path/filepath"
-	"runtime"
-	"strings"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+
+	"github.com/crowdsecurity/crowdsec/pkg/cstest"
 )
 
 func TestSimulationLoading(t *testing.T) {
-
 	testXXFullPath, err := filepath.Abs("./tests/xxx.yaml")
-	if err != nil {
-		panic(err)
-	}
+	require.NoError(t, err)
 
 	badYamlFullPath, err := filepath.Abs("./tests/config.yaml")
-	if err != nil {
-		panic(err)
-	}
+	require.NoError(t, err)
 
 	tests := []struct {
 		name           string
 		Input          *Config
 		expectedResult *SimulationConfig
-		err            string
+		expectedErr    	string
 	}{
 		{
 			name: "basic valid simulation",
@@ -49,17 +45,18 @@ func TestSimulationLoading(t *testing.T) {
 				},
 				Crowdsec: &CrowdsecServiceCfg{},
 			},
+			expectedErr: "simulation.yaml: "+cstest.FileNotFoundMessage,
 		},
 		{
-			name: "basic bad file content",
+			name: "basic bad file name",
 			Input: &Config{
 				ConfigPaths: &ConfigurationPaths{
-					SimulationFilePath: "./tests/config.yaml",
+					SimulationFilePath: "./tests/xxx.yaml",
 					DataDir:            "./data",
 				},
 				Crowdsec: &CrowdsecServiceCfg{},
 			},
-			err: fmt.Sprintf("while unmarshaling simulation file '%s' : yaml: unmarshal errors", badYamlFullPath),
+			expectedErr: fmt.Sprintf("while reading yaml file: open %s: %s", testXXFullPath, cstest.FileNotFoundMessage),
 		},
 		{
 			name: "basic bad file content",
@@ -70,66 +67,29 @@ func TestSimulationLoading(t *testing.T) {
 				},
 				Crowdsec: &CrowdsecServiceCfg{},
 			},
-			err: fmt.Sprintf("while unmarshaling simulation file '%s' : yaml: unmarshal errors", badYamlFullPath),
+			expectedErr: fmt.Sprintf("while unmarshaling simulation file '%s' : yaml: unmarshal errors", badYamlFullPath),
 		},
-	}
-
-	if runtime.GOOS == "windows" {
-		tests = append(tests, struct {
-			name           string
-			Input          *Config
-			expectedResult *SimulationConfig
-			err            string
-		}{
-			name: "basic bad file name",
-			Input: &Config{
-				ConfigPaths: &ConfigurationPaths{
-					SimulationFilePath: "./tests/xxx.yaml",
-					DataDir:            "./data",
-				},
-				Crowdsec: &CrowdsecServiceCfg{},
-			},
-			err: fmt.Sprintf("while reading yaml file: open %s: The system cannot find the file specified.", testXXFullPath),
-		})
-	} else {
-		tests = append(tests, struct {
-			name           string
-			Input          *Config
-			expectedResult *SimulationConfig
-			err            string
-		}{
-			name: "basic bad file name",
+		{
+			name: "basic bad file content",
 			Input: &Config{
 				ConfigPaths: &ConfigurationPaths{
-					SimulationFilePath: "./tests/xxx.yaml",
+					SimulationFilePath: "./tests/config.yaml",
 					DataDir:            "./data",
 				},
 				Crowdsec: &CrowdsecServiceCfg{},
 			},
-			err: fmt.Sprintf("while reading yaml file: open %s: no such file or directory", testXXFullPath),
-		})
+			expectedErr: fmt.Sprintf("while unmarshaling simulation file '%s' : yaml: unmarshal errors", badYamlFullPath),
+		},
 	}
 
-	for idx, test := range tests {
-		err := test.Input.LoadSimulation()
-		if err == nil && test.err != "" {
-			fmt.Printf("TEST '%s': NOK\n", test.name)
-			t.Fatalf("%d/%d expected error, didn't get it", idx, len(tests))
-		}
-		if test.err != "" {
-			if !strings.HasPrefix(fmt.Sprintf("%s", err), test.err) {
-				fmt.Printf("TEST '%s': NOK\n", test.name)
-				t.Fatalf("%d/%d expected '%s' got '%s'", idx, len(tests),
-					test.err,
-					fmt.Sprintf("%s", err))
-			}
-		}
-		isOk := assert.Equal(t, test.expectedResult, test.Input.Crowdsec.SimulationConfig)
-		if !isOk {
-			t.Fatalf("TEST '%s': NOK\n", test.name)
-		} else {
-			fmt.Printf("TEST '%s': OK\n", test.name)
-		}
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			err := tc.Input.LoadSimulation()
+			cstest.RequireErrorContains(t, err, tc.expectedErr)
+
+			assert.Equal(t, tc.expectedResult, tc.Input.Crowdsec.SimulationConfig)
+		})
 	}
 }
 
@@ -150,7 +110,6 @@ func TestIsSimulated(t *testing.T) {
 		SimulationConfig *SimulationConfig
 		Input            string
 		expectedResult   bool
-		err              string
 	}{
 		{
 			name:             "No simulation except (in exclusion)",
@@ -171,13 +130,11 @@ func TestIsSimulated(t *testing.T) {
 			expectedResult:   false,
 		},
 	}
-	for _, test := range tests {
-		IsSimulated := test.SimulationConfig.IsSimulated(test.Input)
-		isOk := assert.Equal(t, test.expectedResult, IsSimulated)
-		if !isOk {
-			fmt.Printf("TEST: '%v' failed", test.name)
-			t.Fatal()
-		}
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			IsSimulated := tc.SimulationConfig.IsSimulated(tc.Input)
+			require.Equal(t, tc.expectedResult, IsSimulated)
+		})
 	}
-
 }

+ 204 - 217
pkg/csplugin/broker_test.go

@@ -14,31 +14,32 @@ import (
 	"time"
 
 	log "github.com/sirupsen/logrus"
-
-	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
-	"github.com/crowdsecurity/crowdsec/pkg/models"
-	"github.com/pkg/errors"
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	"gopkg.in/tomb.v2"
 	"gopkg.in/yaml.v2"
+
+	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
+	"github.com/crowdsecurity/crowdsec/pkg/cstest"
+	"github.com/crowdsecurity/crowdsec/pkg/models"
 )
 
 var testPath string
 
-func setPluginPermTo744() {
-	setPluginPermTo("744")
+func setPluginPermTo744(t *testing.T) {
+	setPluginPermTo(t, "744")
 }
 
-func setPluginPermTo722() {
-	setPluginPermTo("722")
+func setPluginPermTo722(t *testing.T) {
+	setPluginPermTo(t, "722")
 }
 
-func setPluginPermTo724() {
-	setPluginPermTo("724")
+func setPluginPermTo724(t *testing.T) {
+	setPluginPermTo(t, "724")
 }
 func TestGetPluginNameAndTypeFromPath(t *testing.T) {
-	setUp()
-	defer tearDown()
+	setUp(t)
+	defer tearDown(t)
 	type args struct {
 		path string
 	}
@@ -47,7 +48,7 @@ func TestGetPluginNameAndTypeFromPath(t *testing.T) {
 		args    args
 		want    string
 		want1   string
-		wantErr bool
+		expectedErr string
 	}{
 		{
 			name: "valid plugin name, single dash",
@@ -56,16 +57,13 @@ func TestGetPluginNameAndTypeFromPath(t *testing.T) {
 			},
 			want:    "notification",
 			want1:   "gitter",
-			wantErr: false,
 		},
 		{
 			name: "invalid plugin name",
 			args: args{
 				path: "./tests/gitter",
 			},
-			want:    "",
-			want1:   "",
-			wantErr: true,
+			expectedErr: "plugin name ./tests/gitter is invalid. Name should be like {type-name}",
 		},
 		{
 			name: "valid plugin name, multiple dash",
@@ -74,30 +72,23 @@ func TestGetPluginNameAndTypeFromPath(t *testing.T) {
 			},
 			want:    "notification-instant",
 			want1:   "slack",
-			wantErr: false,
 		},
 	}
-	for _, tt := range tests {
-		tt := tt
-		t.Run(tt.name, func(t *testing.T) {
-			got, got1, err := getPluginTypeAndSubtypeFromPath(tt.args.path)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("getPluginNameAndTypeFromPath() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("getPluginNameAndTypeFromPath() got = %v, want %v", got, tt.want)
-			}
-			if got1 != tt.want1 {
-				t.Errorf("getPluginNameAndTypeFromPath() got1 = %v, want %v", got1, tt.want1)
-			}
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			got, got1, err := getPluginTypeAndSubtypeFromPath(tc.args.path)
+			cstest.RequireErrorContains(t, err, tc.expectedErr)
+
+			assert.Equal(t, tc.want, got)
+			assert.Equal(t, tc.want1, got1)
 		})
 	}
 }
 
 func TestListFilesAtPath(t *testing.T) {
-	setUp()
-	defer tearDown()
+	setUp(t)
+	defer tearDown(t)
 	type args struct {
 		path string
 	}
@@ -105,7 +96,7 @@ func TestListFilesAtPath(t *testing.T) {
 		name    string
 		args    args
 		want    []string
-		wantErr bool
+		expectedErr string
 	}{
 		{
 			name: "valid directory",
@@ -122,19 +113,17 @@ func TestListFilesAtPath(t *testing.T) {
 			args: args{
 				path: "./foo/bar/",
 			},
-			wantErr: true,
+			expectedErr: "open ./foo/bar/: " + cstest.FileNotFoundMessage,
 		},
 	}
-	for _, tt := range tests {
-		tt := tt
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := listFilesAtPath(tt.args.path)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("listFilesAtPath() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("listFilesAtPath() = %v, want %v", got, tt.want)
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			got, err := listFilesAtPath(tc.args.path)
+			cstest.RequireErrorContains(t, err, tc.expectedErr)
+
+			if !reflect.DeepEqual(got, tc.want) {
+				t.Errorf("listFilesAtPath() = %v, want %v", got, tc.want)
 			}
 		})
 	}
@@ -147,49 +136,40 @@ func TestBrokerInit(t *testing.T) {
 
 	tests := []struct {
 		name        string
-		action      func()
-		errContains string
-		wantErr     bool
+		action      func(*testing.T)
 		procCfg     csconfig.PluginCfg
+		expectedErr string
 	}{
 		{
-			name:    "valid config",
-			action:  setPluginPermTo744,
-			wantErr: false,
+			name:   "valid config",
+			action: setPluginPermTo744,
 		},
 		{
 			name:        "group writable binary",
-			wantErr:     true,
-			errContains: "notification-dummy is world writable",
+			expectedErr: "notification-dummy is world writable",
 			action:      setPluginPermTo722,
 		},
 		{
 			name:        "group writable binary",
-			wantErr:     true,
-			errContains: "notification-dummy is group writable",
+			expectedErr: "notification-dummy is group writable",
 			action:      setPluginPermTo724,
 		},
 		{
 			name:        "no plugin dir",
-			wantErr:     true,
-			errContains: "no such file or directory",
+			expectedErr: cstest.FileNotFoundMessage,
 			action:      tearDown,
 		},
 		{
 			name:        "no plugin binary",
-			wantErr:     true,
-			errContains: "binary for plugin dummy_default not found",
-			action: func() {
+			expectedErr: "binary for plugin dummy_default not found",
+			action: func(t *testing.T) {
 				err := os.Remove(path.Join(testPath, "notification-dummy"))
-				if err != nil {
-					t.Fatal(err)
-				}
+				require.NoError(t, err)
 			},
 		},
 		{
 			name:        "only specify user",
-			wantErr:     true,
-			errContains: "both plugin user and group must be set",
+			expectedErr: "both plugin user and group must be set",
 			procCfg: csconfig.PluginCfg{
 				User: "123445555551122toto",
 			},
@@ -197,8 +177,7 @@ func TestBrokerInit(t *testing.T) {
 		},
 		{
 			name:        "only specify group",
-			wantErr:     true,
-			errContains: "both plugin user and group must be set",
+			expectedErr: "both plugin user and group must be set",
 			procCfg: csconfig.PluginCfg{
 				Group: "123445555551122toto",
 			},
@@ -206,8 +185,7 @@ func TestBrokerInit(t *testing.T) {
 		},
 		{
 			name:        "Fails to run as root",
-			wantErr:     true,
-			errContains: "operation not permitted",
+			expectedErr: "operation not permitted",
 			procCfg: csconfig.PluginCfg{
 				User:  "root",
 				Group: "root",
@@ -216,8 +194,7 @@ func TestBrokerInit(t *testing.T) {
 		},
 		{
 			name:        "Invalid user and group",
-			wantErr:     true,
-			errContains: "unknown user toto1234",
+			expectedErr: "unknown user toto1234",
 			procCfg: csconfig.PluginCfg{
 				User:  "toto1234",
 				Group: "toto1234",
@@ -226,8 +203,7 @@ func TestBrokerInit(t *testing.T) {
 		},
 		{
 			name:        "Valid user and invalid group",
-			wantErr:     true,
-			errContains: "unknown group toto1234",
+			expectedErr: "unknown group toto1234",
 			procCfg: csconfig.PluginCfg{
 				User:  "nobody",
 				Group: "toto1234",
@@ -236,30 +212,25 @@ func TestBrokerInit(t *testing.T) {
 		},
 	}
 
-	for _, test := range tests {
-		test := test
-		t.Run(test.name, func(t *testing.T) {
-			defer tearDown()
-			buildDummyPlugin()
-			if test.action != nil {
-				test.action()
+	for _, tc := range tests {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			defer tearDown(t)
+			buildDummyPlugin(t)
+			if tc.action != nil {
+				tc.action(t)
 			}
 			pb := PluginBroker{}
 			profiles := csconfig.NewDefaultConfig().API.Server.Profiles
 			profiles = append(profiles, &csconfig.ProfileCfg{
 				Notifications: []string{"dummy_default"},
 			})
-			err := pb.Init(&test.procCfg, profiles, &csconfig.ConfigurationPaths{
+			err := pb.Init(&tc.procCfg, profiles, &csconfig.ConfigurationPaths{
 				PluginDir:       testPath,
 				NotificationDir: "./tests/notifications",
 			})
 			defer pb.Kill()
-			if test.wantErr {
-				assert.ErrorContains(t, err, test.errContains)
-			} else {
-				assert.NoError(t, err)
-			}
-
+			cstest.RequireErrorContains(t, err, tc.expectedErr)
 		})
 	}
 }
@@ -267,91 +238,95 @@ func TestBrokerInit(t *testing.T) {
 func readconfig(t *testing.T, path string) ([]byte, PluginConfig) {
 	var config PluginConfig
 	orig, err := os.ReadFile("tests/notifications/dummy.yaml")
-	if err != nil {
-		t.Fatalf("unable to read config file %s : %s", path, err)
-	}
-	if err := yaml.Unmarshal(orig, &config); err != nil {
-		t.Fatalf("unable to unmarshal config file : %s", err)
-	}
+	require.NoError(t, err,"unable to read config file %s", path)
+
+	err = yaml.Unmarshal(orig, &config)
+	require.NoError(t, err,"unable to unmarshal config file")
+	
 	return orig, config
 }
 
 func writeconfig(t *testing.T, config PluginConfig, path string) {
 	data, err := yaml.Marshal(&config)
-	if err != nil {
-		t.Fatalf("unable to marshal config file : %s", err)
-	}
-	if err := os.WriteFile(path, data, 0644); err != nil {
-		t.Fatalf("unable to write config file %s : %s", path, err)
-	}
+	require.NoError(t, err,"unable to marshal config file")
+
+	err = os.WriteFile(path, data, 0644)
+	require.NoError(t, err,"unable to write config file %s", path)
 }
 
 func TestBrokerNoThreshold(t *testing.T) {
 	var alerts []models.Alert
 	DefaultEmptyTicker = 50 * time.Millisecond
 
-	buildDummyPlugin()
-	setPluginPermTo744()
-	defer tearDown()
-	//init
+	buildDummyPlugin(t)
+	setPluginPermTo744(t)
+	defer tearDown(t)
+
+	// init
 	pluginCfg := csconfig.PluginCfg{}
 	pb := PluginBroker{}
 	profiles := csconfig.NewDefaultConfig().API.Server.Profiles
 	profiles = append(profiles, &csconfig.ProfileCfg{
 		Notifications: []string{"dummy_default"},
 	})
-	//default config
+
+	// default config
 	err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
 		PluginDir:       testPath,
 		NotificationDir: "./tests/notifications",
 	})
+
 	assert.NoError(t, err)
 	tomb := tomb.Tomb{}
+
 	go pb.Run(&tomb)
 	defer pb.Kill()
-	//send one item, it should be processed right now
+
+	// send one item, it should be processed right now
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(200 * time.Millisecond)
-	//we expect one now
+
+	// we expect one now
 	content, err := os.ReadFile("./out")
-	if err != nil {
-		log.Errorf("Error reading file: %s", err)
-	}
+	require.NoError(t, err, "Error reading file")
+
 	err = json.Unmarshal(content, &alerts)
 	assert.NoError(t, err)
-	assert.Equal(t, 1, len(alerts))
-	//remove it
+	assert.Len(t, alerts, 1)
+
+	// remove it
 	os.Remove("./out")
-	//and another one
+
+	// and another one
 	log.Printf("second send")
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(200 * time.Millisecond)
-	//we expect one again, as we cleaned the file
+
+	// we expect one again, as we cleaned the file
 	content, err = os.ReadFile("./out")
-	if err != nil {
-		log.Errorf("Error reading file: %s", err)
-	}
+	require.NoError(t, err, "Error reading file")
+
 	err = json.Unmarshal(content, &alerts)
 	log.Printf("content-> %s", content)
 	assert.NoError(t, err)
-	assert.Equal(t, 1, len(alerts))
+	assert.Len(t, alerts, 1)
 }
 
 func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
-	//test grouping by "time"
+	// test grouping by "time"
 	DefaultEmptyTicker = 50 * time.Millisecond
-	buildDummyPlugin()
-	setPluginPermTo744()
-	defer tearDown()
+	buildDummyPlugin(t)
+	setPluginPermTo744(t)
+	defer tearDown(t)
 
-	//init
+	// init
 	pluginCfg := csconfig.PluginCfg{}
 	pb := PluginBroker{}
 	profiles := csconfig.NewDefaultConfig().API.Server.Profiles
 	profiles = append(profiles, &csconfig.ProfileCfg{
 		Notifications: []string{"dummy_default"},
 	})
-	//set groupwait and groupthreshold, should honor whichever comes first
+	// set groupwait and groupthreshold, should honor whichever comes first
 	raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
 	cfg.GroupThreshold = 4
 	cfg.GroupWait = 1 * time.Second
@@ -362,42 +337,46 @@ func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
 	})
 	assert.NoError(t, err)
 	tomb := tomb.Tomb{}
+
 	go pb.Run(&tomb)
 	defer pb.Kill()
-	//send data
+	// send data
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(500 * time.Millisecond)
-	//because of group threshold, we shouldn't have data yet
+	// because of group threshold, we shouldn't have data yet
 	assert.NoFileExists(t, "./out")
 	time.Sleep(1 * time.Second)
-	//after 1 seconds, we should have data
+	// after 1 seconds, we should have data
 	content, err := os.ReadFile("./out")
 	assert.NoError(t, err)
+
 	var alerts []models.Alert
 	err = json.Unmarshal(content, &alerts)
 	assert.NoError(t, err)
-	assert.Equal(t, 3, len(alerts))
-	//restore config
-	if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
-		t.Fatalf("unable to write config file %s", err)
-	}
+	assert.Len(t, alerts, 3)
+
+	// restore config
+	err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
+	require.NoError(t, err,"unable to write config file")
 }
 
 func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
 	DefaultEmptyTicker = 50 * time.Millisecond
-	buildDummyPlugin()
-	setPluginPermTo744()
-	defer tearDown()
-	//init
+	buildDummyPlugin(t)
+	setPluginPermTo(t, "744")
+	defer tearDown(t)
+
+	// init
 	pluginCfg := csconfig.PluginCfg{}
 	pb := PluginBroker{}
 	profiles := csconfig.NewDefaultConfig().API.Server.Profiles
 	profiles = append(profiles, &csconfig.ProfileCfg{
 		Notifications: []string{"dummy_default"},
 	})
-	//set groupwait and groupthreshold, should honor whichever comes first
+
+	// set groupwait and groupthreshold, should honor whichever comes first
 	raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
 	cfg.GroupThreshold = 4
 	cfg.GroupWait = 4 * time.Second
@@ -408,46 +387,51 @@ func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
 	})
 	assert.NoError(t, err)
 	tomb := tomb.Tomb{}
+
 	go pb.Run(&tomb)
 	defer pb.Kill()
-	//send data
+
+	// send data
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(100 * time.Millisecond)
-	//because of group threshold, we shouldn't have data yet
+
+	// because of group threshold, we shouldn't have data yet
 	assert.NoFileExists(t, "./out")
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(100 * time.Millisecond)
-	//and now we should
+
+	// and now we should
 	content, err := os.ReadFile("./out")
-	if err != nil {
-		log.Errorf("Error reading file: %s", err)
-	}
+	require.NoError(t, err, "Error reading file")
+
 	var alerts []models.Alert
 	err = json.Unmarshal(content, &alerts)
 	assert.NoError(t, err)
-	assert.Equal(t, 4, len(alerts))
-	//restore config
-	if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
-		t.Fatalf("unable to write config file %s", err)
-	}
+	assert.Len(t, alerts, 4)
+
+	// restore config
+	err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
+	require.NoError(t, err,"unable to write config file")
 }
 
 func TestBrokerRunGroupThreshold(t *testing.T) {
-	//test grouping by "size"
+	// test grouping by "size"
 	DefaultEmptyTicker = 50 * time.Millisecond
-	buildDummyPlugin()
-	setPluginPermTo744()
-	defer tearDown()
-	//init
+	buildDummyPlugin(t)
+	setPluginPermTo(t, "744")
+	defer tearDown(t)
+
+	// init
 	pluginCfg := csconfig.PluginCfg{}
 	pb := PluginBroker{}
 	profiles := csconfig.NewDefaultConfig().API.Server.Profiles
 	profiles = append(profiles, &csconfig.ProfileCfg{
 		Notifications: []string{"dummy_default"},
 	})
-	//set groupwait
+
+	// set groupwait
 	raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
 	cfg.GroupThreshold = 4
 	writeconfig(t, cfg, "tests/notifications/dummy.yaml")
@@ -455,49 +439,55 @@ func TestBrokerRunGroupThreshold(t *testing.T) {
 		PluginDir:       testPath,
 		NotificationDir: "./tests/notifications",
 	})
+
 	assert.NoError(t, err)
 	tomb := tomb.Tomb{}
+
 	go pb.Run(&tomb)
 	defer pb.Kill()
-	//send data
+
+	// send data
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(100 * time.Millisecond)
-	//because of group threshold, we shouldn't have data yet
+
+	// because of group threshold, we shouldn't have data yet
 	assert.NoFileExists(t, "./out")
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(100 * time.Millisecond)
-	//and now we should
+
+	// and now we should
 	content, err := os.ReadFile("./out")
-	if err != nil {
-		log.Errorf("Error reading file: %s", err)
-	}
+	require.NoError(t, err, "Error reading file")
+
 	var alerts []models.Alert
 	err = json.Unmarshal(content, &alerts)
 	assert.NoError(t, err)
-	assert.Equal(t, 4, len(alerts))
-	//restore config
-	if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
-		t.Fatalf("unable to write config file %s", err)
-	}
+	assert.Len(t, alerts, 4)
+
+	// restore config
+	err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
+	require.NoError(t, err, "unable to write config file")
 }
 
 func TestBrokerRunTimeThreshold(t *testing.T) {
 	DefaultEmptyTicker = 50 * time.Millisecond
-	buildDummyPlugin()
-	setPluginPermTo744()
-	defer tearDown()
-	//init
+	buildDummyPlugin(t)
+	setPluginPermTo(t, "744")
+	defer tearDown(t)
+
+	// init
 	pluginCfg := csconfig.PluginCfg{}
 	pb := PluginBroker{}
 	profiles := csconfig.NewDefaultConfig().API.Server.Profiles
 	profiles = append(profiles, &csconfig.ProfileCfg{
 		Notifications: []string{"dummy_default"},
 	})
-	//set groupwait
+
+	// set groupwait
 	raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
-	cfg.GroupWait = time.Duration(1 * time.Second) //nolint:unconvert
+	cfg.GroupWait = 1 * time.Second
 	writeconfig(t, cfg, "tests/notifications/dummy.yaml")
 	err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
 		PluginDir:       testPath,
@@ -505,34 +495,37 @@ func TestBrokerRunTimeThreshold(t *testing.T) {
 	})
 	assert.NoError(t, err)
 	tomb := tomb.Tomb{}
+
 	go pb.Run(&tomb)
 	defer pb.Kill()
-	//send data
+
+	// send data
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
 	time.Sleep(200 * time.Millisecond)
-	//we shouldn't have data yet
+
+	// we shouldn't have data yet
 	assert.NoFileExists(t, "./out")
 	time.Sleep(1 * time.Second)
-	//and now we should
+
+	// and now we should
 	content, err := os.ReadFile("./out")
-	if err != nil {
-		log.Errorf("Error reading file: %s", err)
-	}
+	require.NoError(t, err, "Error reading file")
+
 	var alerts []models.Alert
 	err = json.Unmarshal(content, &alerts)
 	assert.NoError(t, err)
-	assert.Equal(t, 1, len(alerts))
-	//restore config
-	if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
-		t.Fatalf("unable to write config file %s", err)
-	}
+	assert.Len(t, alerts, 1)
+
+	// restore config
+	err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
+	require.NoError(t, err, "unable to write config file %s", err)
 }
 
 func TestBrokerRunSimple(t *testing.T) {
 	DefaultEmptyTicker = 50 * time.Millisecond
-	buildDummyPlugin()
-	setPluginPermTo744()
-	defer tearDown()
+	buildDummyPlugin(t)
+	setPluginPermTo(t, "744")
+	defer tearDown(t)
 	pluginCfg := csconfig.PluginCfg{}
 	pb := PluginBroker{}
 	profiles := csconfig.NewDefaultConfig().API.Server.Profiles
@@ -545,10 +538,12 @@ func TestBrokerRunSimple(t *testing.T) {
 	})
 	assert.NoError(t, err)
 	tomb := tomb.Tomb{}
+
 	go pb.Run(&tomb)
 	defer pb.Kill()
 
 	assert.NoFileExists(t, "./out")
+
 	defer os.Remove("./out")
 
 	pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
@@ -556,62 +551,54 @@ func TestBrokerRunSimple(t *testing.T) {
 	time.Sleep(time.Millisecond * 200)
 
 	content, err := os.ReadFile("./out")
-	if err != nil {
-		log.Errorf("Error reading file: %s", err)
-	}
+	require.NoError(t, err, "Error reading file")
+
 	var alerts []models.Alert
 	err = json.Unmarshal(content, &alerts)
 	assert.NoError(t, err)
-	assert.Equal(t, 2, len(alerts))
+	assert.Len(t, alerts, 2)
 }
 
-func buildDummyPlugin() {
+func buildDummyPlugin(t *testing.T) {
 	dir, err := os.MkdirTemp("./tests", "cs_plugin_test")
-	if err != nil {
-		log.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	cmd := exec.Command("go", "build", "-o", path.Join(dir, "notification-dummy"), "../../plugins/notifications/dummy/")
-	if err := cmd.Run(); err != nil {
-		log.Fatal(err)
-	}
+	err = cmd.Run()
+	require.NoError(t, err, "while building dummy plugin")
+
 	testPath = dir
 	os.Remove("./out")
 }
 
-func setPluginPermTo(perm string) {
+func setPluginPermTo(t *testing.T, perm string) {
 	if runtime.GOOS != "windows" {
-		if err := exec.Command("chmod", perm, path.Join(testPath, "notification-dummy")).Run(); err != nil {
-			log.Fatal(errors.Wrapf(err, "chmod 744 %s", path.Join(testPath, "notification-dummy")))
-		}
+		err := exec.Command("chmod", perm, path.Join(testPath, "notification-dummy")).Run()
+		require.NoError(t, err, "chmod 744 %s", path.Join(testPath, "notification-dummy"))
 	}
 }
 
-func setUp() {
+func setUp(t *testing.T) {
 	dir, err := os.MkdirTemp("./", "cs_plugin_test")
-	if err != nil {
-		log.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	f, err := os.Create(path.Join(dir, "slack"))
-	if err != nil {
-		log.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	f.Close()
 	f, err = os.Create(path.Join(dir, "notification-gitter"))
-	if err != nil {
-		log.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	f.Close()
 	err = os.Mkdir(path.Join(dir, "dummy_dir"), 0666)
-	if err != nil {
-		log.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	testPath = dir
 }
 
-func tearDown() {
+func tearDown(t *testing.T) {
 	err := os.RemoveAll(testPath)
-	if err != nil {
-		log.Fatal(err)
-	}
+	require.NoError(t, err)
+
 	os.Remove("./out")
 }

+ 5 - 3
pkg/csplugin/broker_win_test.go

@@ -12,11 +12,13 @@ import (
 	"testing"
 	"time"
 
+	"github.com/stretchr/testify/assert"
+	"gopkg.in/tomb.v2"
+
 	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
+	"github.com/crowdsecurity/crowdsec/pkg/cstest"
 	"github.com/crowdsecurity/crowdsec/pkg/models"
 	"github.com/crowdsecurity/crowdsec/pkg/types"
-	"github.com/stretchr/testify/assert"
-	"gopkg.in/tomb.v2"
 )
 
 /*
@@ -145,7 +147,7 @@ func TestBrokerInit(t *testing.T) {
 		{
 			name:        "no plugin dir",
 			wantErr:     true,
-			errContains: "The system cannot find the file specified.",
+			errContains: cstest.FileNotFoundMessage,
 			action:      tearDown,
 		},
 		{

+ 5 - 0
pkg/cstest/filenotfound_unix.go

@@ -0,0 +1,5 @@
+//go:build unix
+
+package cstest
+
+const FileNotFoundMessage = "no such file or directory"

+ 5 - 0
pkg/cstest/filenotfound_windows.go

@@ -0,0 +1,5 @@
+//go:build windows
+
+package cstest
+
+const FileNotFoundMessage = "The system cannot find the file specified."