refactor broker_test.go, extract cstest/filenotfound*.go (#1815)
This commit is contained in:
parent
a96b3e077d
commit
ec0d2a5ed2
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
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)
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -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,6 +45,18 @@ func TestSimulationLoading(t *testing.T) {
|
|||
},
|
||||
Crowdsec: &CrowdsecServiceCfg{},
|
||||
},
|
||||
expectedErr: "simulation.yaml: "+cstest.FileNotFoundMessage,
|
||||
},
|
||||
{
|
||||
name: "basic bad file name",
|
||||
Input: &Config{
|
||||
ConfigPaths: &ConfigurationPaths{
|
||||
SimulationFilePath: "./tests/xxx.yaml",
|
||||
DataDir: "./data",
|
||||
},
|
||||
Crowdsec: &CrowdsecServiceCfg{},
|
||||
},
|
||||
expectedErr: fmt.Sprintf("while reading yaml file: open %s: %s", testXXFullPath, cstest.FileNotFoundMessage),
|
||||
},
|
||||
{
|
||||
name: "basic bad file content",
|
||||
|
@ -59,7 +67,7 @@ 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),
|
||||
},
|
||||
{
|
||||
name: "basic bad file content",
|
||||
|
@ -70,66 +78,18 @@ 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",
|
||||
Input: &Config{
|
||||
ConfigPaths: &ConfigurationPaths{
|
||||
SimulationFilePath: "./tests/xxx.yaml",
|
||||
DataDir: "./data",
|
||||
},
|
||||
Crowdsec: &CrowdsecServiceCfg{},
|
||||
},
|
||||
err: fmt.Sprintf("while reading yaml file: open %s: no such file or directory", testXXFullPath),
|
||||
})
|
||||
}
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := tc.Input.LoadSimulation()
|
||||
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||
|
||||
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)
|
||||
}
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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: "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,32 +238,30 @@ 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()
|
||||
buildDummyPlugin(t)
|
||||
setPluginPermTo744(t)
|
||||
defer tearDown(t)
|
||||
|
||||
// init
|
||||
pluginCfg := csconfig.PluginCfg{}
|
||||
pb := PluginBroker{}
|
||||
|
@ -300,49 +269,55 @@ func TestBrokerNoThreshold(t *testing.T) {
|
|||
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||
Notifications: []string{"dummy_default"},
|
||||
})
|
||||
|
||||
// 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
|
||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
// 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))
|
||||
assert.Len(t, alerts, 1)
|
||||
|
||||
// remove it
|
||||
os.Remove("./out")
|
||||
|
||||
// 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
|
||||
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"
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
buildDummyPlugin()
|
||||
setPluginPermTo744()
|
||||
defer tearDown()
|
||||
buildDummyPlugin(t)
|
||||
setPluginPermTo744(t)
|
||||
defer tearDown(t)
|
||||
|
||||
// init
|
||||
pluginCfg := csconfig.PluginCfg{}
|
||||
|
@ -362,6 +337,7 @@ func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
|||
})
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
|
||||
go pb.Run(&tomb)
|
||||
defer pb.Kill()
|
||||
// send data
|
||||
|
@ -375,21 +351,23 @@ func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
|||
// 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))
|
||||
assert.Len(t, alerts, 3)
|
||||
|
||||
// restore config
|
||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
||||
t.Fatalf("unable to write config file %s", err)
|
||||
}
|
||||
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()
|
||||
buildDummyPlugin(t)
|
||||
setPluginPermTo(t, "744")
|
||||
defer tearDown(t)
|
||||
|
||||
// init
|
||||
pluginCfg := csconfig.PluginCfg{}
|
||||
pb := PluginBroker{}
|
||||
|
@ -397,6 +375,7 @@ func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
|
|||
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||
Notifications: []string{"dummy_default"},
|
||||
})
|
||||
|
||||
// set groupwait and groupthreshold, should honor whichever comes first
|
||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||
cfg.GroupThreshold = 4
|
||||
|
@ -408,38 +387,42 @@ func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
|
|||
})
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
|
||||
go pb.Run(&tomb)
|
||||
defer pb.Kill()
|
||||
|
||||
// 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
|
||||
assert.NoFileExists(t, "./out")
|
||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// 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))
|
||||
assert.Len(t, alerts, 4)
|
||||
|
||||
// restore config
|
||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
||||
t.Fatalf("unable to write config file %s", err)
|
||||
}
|
||||
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"
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
buildDummyPlugin()
|
||||
setPluginPermTo744()
|
||||
defer tearDown()
|
||||
buildDummyPlugin(t)
|
||||
setPluginPermTo(t, "744")
|
||||
defer tearDown(t)
|
||||
|
||||
// init
|
||||
pluginCfg := csconfig.PluginCfg{}
|
||||
pb := PluginBroker{}
|
||||
|
@ -447,6 +430,7 @@ func TestBrokerRunGroupThreshold(t *testing.T) {
|
|||
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||
Notifications: []string{"dummy_default"},
|
||||
})
|
||||
|
||||
// set groupwait
|
||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||
cfg.GroupThreshold = 4
|
||||
|
@ -455,39 +439,44 @@ 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
|
||||
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
|
||||
assert.NoFileExists(t, "./out")
|
||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// 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))
|
||||
assert.Len(t, alerts, 4)
|
||||
|
||||
// restore config
|
||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
||||
t.Fatalf("unable to write config file %s", err)
|
||||
}
|
||||
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()
|
||||
buildDummyPlugin(t)
|
||||
setPluginPermTo(t, "744")
|
||||
defer tearDown(t)
|
||||
|
||||
// init
|
||||
pluginCfg := csconfig.PluginCfg{}
|
||||
pb := PluginBroker{}
|
||||
|
@ -495,9 +484,10 @@ func TestBrokerRunTimeThreshold(t *testing.T) {
|
|||
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||
Notifications: []string{"dummy_default"},
|
||||
})
|
||||
|
||||
// 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
|
||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
// we shouldn't have data yet
|
||||
assert.NoFileExists(t, "./out")
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// 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))
|
||||
assert.Len(t, alerts, 1)
|
||||
|
||||
// restore config
|
||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
||||
t.Fatalf("unable to write config file %s", err)
|
||||
}
|
||||
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")
|
||||
}
|
||||
|
|
|
@ -12,11 +12,13 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
||||
"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"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -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
pkg/cstest/filenotfound_unix.go
Normal file
5
pkg/cstest/filenotfound_unix.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
//go:build unix
|
||||
|
||||
package cstest
|
||||
|
||||
const FileNotFoundMessage = "no such file or directory"
|
5
pkg/cstest/filenotfound_windows.go
Normal file
5
pkg/cstest/filenotfound_windows.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
//go:build windows
|
||||
|
||||
package cstest
|
||||
|
||||
const FileNotFoundMessage = "The system cannot find the file specified."
|
Loading…
Reference in a new issue