refactor broker_test.go, extract cstest/filenotfound*.go (#1815)
This commit is contained in:
parent
a96b3e077d
commit
ec0d2a5ed2
|
@ -6,16 +6,17 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
tomb "gopkg.in/tomb.v2"
|
tomb "gopkg.in/tomb.v2"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
"gotest.tools/v3/assert"
|
"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 {
|
type MockSource struct {
|
||||||
|
@ -226,7 +227,7 @@ func TestLoadAcquisitionFromFile(t *testing.T) {
|
||||||
Config: csconfig.CrowdsecServiceCfg{
|
Config: csconfig.CrowdsecServiceCfg{
|
||||||
AcquisitionFiles: []string{"does_not_exist"},
|
AcquisitionFiles: []string{"does_not_exist"},
|
||||||
},
|
},
|
||||||
ExpectedError: "can't open does_not_exist",
|
ExpectedError: cstest.FileNotFoundMessage,
|
||||||
ExpectedLen: 0,
|
ExpectedLen: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -282,18 +283,8 @@ func TestLoadAcquisitionFromFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
dss, err := LoadAcquisitionFromFile(&test.Config)
|
dss, err := LoadAcquisitionFromFile(&test.Config)
|
||||||
if test.ExpectedError != "" {
|
cstest.RequireErrorContains(t, err, 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)
|
|
||||||
}
|
|
||||||
if len(dss) != test.ExpectedLen {
|
if len(dss) != test.ExpectedLen {
|
||||||
t.Fatalf("%s : expected %d datasources got %d", test.TestName, test.ExpectedLen, len(dss))
|
t.Fatalf("%s : expected %d datasources got %d", test.TestName, test.ExpectedLen, len(dss))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,20 @@
|
||||||
package csconfig
|
package csconfig
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"runtime"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/cstest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNormalLoad(t *testing.T) {
|
func TestNormalLoad(t *testing.T) {
|
||||||
|
|
||||||
_, err := NewConfig("./tests/config.yaml", false, false)
|
_, err := NewConfig("./tests/config.yaml", false, false)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatalf("unexpected error %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = NewConfig("./tests/xxx.yaml", false, false)
|
_, err = NewConfig("./tests/xxx.yaml", false, false)
|
||||||
if runtime.GOOS != "windows" {
|
assert.EqualError(t, err, "while reading yaml file: open ./tests/xxx.yaml: "+cstest.FileNotFoundMessage)
|
||||||
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.")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = NewConfig("./tests/simulation.yaml", false, false)
|
_, 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")
|
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 {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
expectedResult *Config
|
expectedResult *Config
|
||||||
err string
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "new configuration: basic",
|
name: "new configuration: basic",
|
||||||
expectedResult: &Config{},
|
expectedResult: &Config{},
|
||||||
err: "",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, tc := range tests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
result := &Config{}
|
result := &Config{}
|
||||||
isOk := assert.Equal(t, test.expectedResult, result)
|
assert.Equal(t, tc.expectedResult, result)
|
||||||
if !isOk {
|
})
|
||||||
t.Fatalf("TEST '%s': NOK", test.name)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("TEST '%s': OK\n", test.name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDefaultConfig(t *testing.T) {
|
func TestDefaultConfig(t *testing.T) {
|
||||||
x := NewDefaultConfig()
|
x := NewDefaultConfig()
|
||||||
if err := x.Dump(); err != nil {
|
err := x.Dump()
|
||||||
log.Fatal(err)
|
require.NoError(t, err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,30 +3,26 @@ package csconfig
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/crowdsecurity/crowdsec/pkg/cstest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSimulationLoading(t *testing.T) {
|
func TestSimulationLoading(t *testing.T) {
|
||||||
|
|
||||||
testXXFullPath, err := filepath.Abs("./tests/xxx.yaml")
|
testXXFullPath, err := filepath.Abs("./tests/xxx.yaml")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
badYamlFullPath, err := filepath.Abs("./tests/config.yaml")
|
badYamlFullPath, err := filepath.Abs("./tests/config.yaml")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
Input *Config
|
Input *Config
|
||||||
expectedResult *SimulationConfig
|
expectedResult *SimulationConfig
|
||||||
err string
|
expectedErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "basic valid simulation",
|
name: "basic valid simulation",
|
||||||
|
@ -49,6 +45,18 @@ func TestSimulationLoading(t *testing.T) {
|
||||||
},
|
},
|
||||||
Crowdsec: &CrowdsecServiceCfg{},
|
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",
|
name: "basic bad file content",
|
||||||
|
@ -59,7 +67,7 @@ func TestSimulationLoading(t *testing.T) {
|
||||||
},
|
},
|
||||||
Crowdsec: &CrowdsecServiceCfg{},
|
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",
|
name: "basic bad file content",
|
||||||
|
@ -70,66 +78,18 @@ func TestSimulationLoading(t *testing.T) {
|
||||||
},
|
},
|
||||||
Crowdsec: &CrowdsecServiceCfg{},
|
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" {
|
for _, tc := range tests {
|
||||||
tests = append(tests, struct {
|
tc := tc
|
||||||
name string
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
Input *Config
|
err := tc.Input.LoadSimulation()
|
||||||
expectedResult *SimulationConfig
|
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||||
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 idx, test := range tests {
|
assert.Equal(t, tc.expectedResult, tc.Input.Crowdsec.SimulationConfig)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +110,6 @@ func TestIsSimulated(t *testing.T) {
|
||||||
SimulationConfig *SimulationConfig
|
SimulationConfig *SimulationConfig
|
||||||
Input string
|
Input string
|
||||||
expectedResult bool
|
expectedResult bool
|
||||||
err string
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "No simulation except (in exclusion)",
|
name: "No simulation except (in exclusion)",
|
||||||
|
@ -171,13 +130,11 @@ func TestIsSimulated(t *testing.T) {
|
||||||
expectedResult: false,
|
expectedResult: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, tc := range tests {
|
||||||
IsSimulated := test.SimulationConfig.IsSimulated(test.Input)
|
tc := tc
|
||||||
isOk := assert.Equal(t, test.expectedResult, IsSimulated)
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
if !isOk {
|
IsSimulated := tc.SimulationConfig.IsSimulated(tc.Input)
|
||||||
fmt.Printf("TEST: '%v' failed", test.name)
|
require.Equal(t, tc.expectedResult, IsSimulated)
|
||||||
t.Fatal()
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,31 +14,32 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
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/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/tomb.v2"
|
"gopkg.in/tomb.v2"
|
||||||
"gopkg.in/yaml.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
|
var testPath string
|
||||||
|
|
||||||
func setPluginPermTo744() {
|
func setPluginPermTo744(t *testing.T) {
|
||||||
setPluginPermTo("744")
|
setPluginPermTo(t, "744")
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPluginPermTo722() {
|
func setPluginPermTo722(t *testing.T) {
|
||||||
setPluginPermTo("722")
|
setPluginPermTo(t, "722")
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPluginPermTo724() {
|
func setPluginPermTo724(t *testing.T) {
|
||||||
setPluginPermTo("724")
|
setPluginPermTo(t, "724")
|
||||||
}
|
}
|
||||||
func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||||
setUp()
|
setUp(t)
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
type args struct {
|
type args struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
@ -47,7 +48,7 @@ func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||||
args args
|
args args
|
||||||
want string
|
want string
|
||||||
want1 string
|
want1 string
|
||||||
wantErr bool
|
expectedErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid plugin name, single dash",
|
name: "valid plugin name, single dash",
|
||||||
|
@ -56,16 +57,13 @@ func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||||
},
|
},
|
||||||
want: "notification",
|
want: "notification",
|
||||||
want1: "gitter",
|
want1: "gitter",
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid plugin name",
|
name: "invalid plugin name",
|
||||||
args: args{
|
args: args{
|
||||||
path: "./tests/gitter",
|
path: "./tests/gitter",
|
||||||
},
|
},
|
||||||
want: "",
|
expectedErr: "plugin name ./tests/gitter is invalid. Name should be like {type-name}",
|
||||||
want1: "",
|
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid plugin name, multiple dash",
|
name: "valid plugin name, multiple dash",
|
||||||
|
@ -74,30 +72,23 @@ func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||||
},
|
},
|
||||||
want: "notification-instant",
|
want: "notification-instant",
|
||||||
want1: "slack",
|
want1: "slack",
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tc := range tests {
|
||||||
tt := tt
|
tc := tc
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
got, got1, err := getPluginTypeAndSubtypeFromPath(tt.args.path)
|
got, got1, err := getPluginTypeAndSubtypeFromPath(tc.args.path)
|
||||||
if (err != nil) != tt.wantErr {
|
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||||
t.Errorf("getPluginNameAndTypeFromPath() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
assert.Equal(t, tc.want, got)
|
||||||
}
|
assert.Equal(t, tc.want1, got1)
|
||||||
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)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListFilesAtPath(t *testing.T) {
|
func TestListFilesAtPath(t *testing.T) {
|
||||||
setUp()
|
setUp(t)
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
type args struct {
|
type args struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
@ -105,7 +96,7 @@ func TestListFilesAtPath(t *testing.T) {
|
||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
want []string
|
want []string
|
||||||
wantErr bool
|
expectedErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid directory",
|
name: "valid directory",
|
||||||
|
@ -122,19 +113,17 @@ func TestListFilesAtPath(t *testing.T) {
|
||||||
args: args{
|
args: args{
|
||||||
path: "./foo/bar/",
|
path: "./foo/bar/",
|
||||||
},
|
},
|
||||||
wantErr: true,
|
expectedErr: "open ./foo/bar/: " + cstest.FileNotFoundMessage,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tc := range tests {
|
||||||
tt := tt
|
tc := tc
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
got, err := listFilesAtPath(tt.args.path)
|
got, err := listFilesAtPath(tc.args.path)
|
||||||
if (err != nil) != tt.wantErr {
|
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||||
t.Errorf("listFilesAtPath() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
return
|
if !reflect.DeepEqual(got, tc.want) {
|
||||||
}
|
t.Errorf("listFilesAtPath() = %v, want %v", got, tc.want)
|
||||||
if !reflect.DeepEqual(got, tt.want) {
|
|
||||||
t.Errorf("listFilesAtPath() = %v, want %v", got, tt.want)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -147,49 +136,40 @@ func TestBrokerInit(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
action func()
|
action func(*testing.T)
|
||||||
errContains string
|
|
||||||
wantErr bool
|
|
||||||
procCfg csconfig.PluginCfg
|
procCfg csconfig.PluginCfg
|
||||||
|
expectedErr string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid config",
|
name: "valid config",
|
||||||
action: setPluginPermTo744,
|
action: setPluginPermTo744,
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "group writable binary",
|
name: "group writable binary",
|
||||||
wantErr: true,
|
expectedErr: "notification-dummy is world writable",
|
||||||
errContains: "notification-dummy is world writable",
|
|
||||||
action: setPluginPermTo722,
|
action: setPluginPermTo722,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "group writable binary",
|
name: "group writable binary",
|
||||||
wantErr: true,
|
expectedErr: "notification-dummy is group writable",
|
||||||
errContains: "notification-dummy is group writable",
|
|
||||||
action: setPluginPermTo724,
|
action: setPluginPermTo724,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no plugin dir",
|
name: "no plugin dir",
|
||||||
wantErr: true,
|
expectedErr: cstest.FileNotFoundMessage,
|
||||||
errContains: "no such file or directory",
|
|
||||||
action: tearDown,
|
action: tearDown,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no plugin binary",
|
name: "no plugin binary",
|
||||||
wantErr: true,
|
expectedErr: "binary for plugin dummy_default not found",
|
||||||
errContains: "binary for plugin dummy_default not found",
|
action: func(t *testing.T) {
|
||||||
action: func() {
|
|
||||||
err := os.Remove(path.Join(testPath, "notification-dummy"))
|
err := os.Remove(path.Join(testPath, "notification-dummy"))
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "only specify user",
|
name: "only specify user",
|
||||||
wantErr: true,
|
expectedErr: "both plugin user and group must be set",
|
||||||
errContains: "both plugin user and group must be set",
|
|
||||||
procCfg: csconfig.PluginCfg{
|
procCfg: csconfig.PluginCfg{
|
||||||
User: "123445555551122toto",
|
User: "123445555551122toto",
|
||||||
},
|
},
|
||||||
|
@ -197,8 +177,7 @@ func TestBrokerInit(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "only specify group",
|
name: "only specify group",
|
||||||
wantErr: true,
|
expectedErr: "both plugin user and group must be set",
|
||||||
errContains: "both plugin user and group must be set",
|
|
||||||
procCfg: csconfig.PluginCfg{
|
procCfg: csconfig.PluginCfg{
|
||||||
Group: "123445555551122toto",
|
Group: "123445555551122toto",
|
||||||
},
|
},
|
||||||
|
@ -206,8 +185,7 @@ func TestBrokerInit(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Fails to run as root",
|
name: "Fails to run as root",
|
||||||
wantErr: true,
|
expectedErr: "operation not permitted",
|
||||||
errContains: "operation not permitted",
|
|
||||||
procCfg: csconfig.PluginCfg{
|
procCfg: csconfig.PluginCfg{
|
||||||
User: "root",
|
User: "root",
|
||||||
Group: "root",
|
Group: "root",
|
||||||
|
@ -216,8 +194,7 @@ func TestBrokerInit(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid user and group",
|
name: "Invalid user and group",
|
||||||
wantErr: true,
|
expectedErr: "unknown user toto1234",
|
||||||
errContains: "unknown user toto1234",
|
|
||||||
procCfg: csconfig.PluginCfg{
|
procCfg: csconfig.PluginCfg{
|
||||||
User: "toto1234",
|
User: "toto1234",
|
||||||
Group: "toto1234",
|
Group: "toto1234",
|
||||||
|
@ -226,8 +203,7 @@ func TestBrokerInit(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Valid user and invalid group",
|
name: "Valid user and invalid group",
|
||||||
wantErr: true,
|
expectedErr: "unknown group toto1234",
|
||||||
errContains: "unknown group toto1234",
|
|
||||||
procCfg: csconfig.PluginCfg{
|
procCfg: csconfig.PluginCfg{
|
||||||
User: "nobody",
|
User: "nobody",
|
||||||
Group: "toto1234",
|
Group: "toto1234",
|
||||||
|
@ -236,30 +212,25 @@ func TestBrokerInit(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, tc := range tests {
|
||||||
test := test
|
tc := tc
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
buildDummyPlugin()
|
buildDummyPlugin(t)
|
||||||
if test.action != nil {
|
if tc.action != nil {
|
||||||
test.action()
|
tc.action(t)
|
||||||
}
|
}
|
||||||
pb := PluginBroker{}
|
pb := PluginBroker{}
|
||||||
profiles := csconfig.NewDefaultConfig().API.Server.Profiles
|
profiles := csconfig.NewDefaultConfig().API.Server.Profiles
|
||||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||||
Notifications: []string{"dummy_default"},
|
Notifications: []string{"dummy_default"},
|
||||||
})
|
})
|
||||||
err := pb.Init(&test.procCfg, profiles, &csconfig.ConfigurationPaths{
|
err := pb.Init(&tc.procCfg, profiles, &csconfig.ConfigurationPaths{
|
||||||
PluginDir: testPath,
|
PluginDir: testPath,
|
||||||
NotificationDir: "./tests/notifications",
|
NotificationDir: "./tests/notifications",
|
||||||
})
|
})
|
||||||
defer pb.Kill()
|
defer pb.Kill()
|
||||||
if test.wantErr {
|
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||||
assert.ErrorContains(t, err, test.errContains)
|
|
||||||
} else {
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,32 +238,30 @@ func TestBrokerInit(t *testing.T) {
|
||||||
func readconfig(t *testing.T, path string) ([]byte, PluginConfig) {
|
func readconfig(t *testing.T, path string) ([]byte, PluginConfig) {
|
||||||
var config PluginConfig
|
var config PluginConfig
|
||||||
orig, err := os.ReadFile("tests/notifications/dummy.yaml")
|
orig, err := os.ReadFile("tests/notifications/dummy.yaml")
|
||||||
if err != nil {
|
require.NoError(t, err,"unable to read config file %s", path)
|
||||||
t.Fatalf("unable to read config file %s : %s", path, err)
|
|
||||||
}
|
err = yaml.Unmarshal(orig, &config)
|
||||||
if err := yaml.Unmarshal(orig, &config); err != nil {
|
require.NoError(t, err,"unable to unmarshal config file")
|
||||||
t.Fatalf("unable to unmarshal config file : %s", err)
|
|
||||||
}
|
|
||||||
return orig, config
|
return orig, config
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeconfig(t *testing.T, config PluginConfig, path string) {
|
func writeconfig(t *testing.T, config PluginConfig, path string) {
|
||||||
data, err := yaml.Marshal(&config)
|
data, err := yaml.Marshal(&config)
|
||||||
if err != nil {
|
require.NoError(t, err,"unable to marshal config file")
|
||||||
t.Fatalf("unable to marshal config file : %s", err)
|
|
||||||
}
|
err = os.WriteFile(path, data, 0644)
|
||||||
if err := os.WriteFile(path, data, 0644); err != nil {
|
require.NoError(t, err,"unable to write config file %s", path)
|
||||||
t.Fatalf("unable to write config file %s : %s", path, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBrokerNoThreshold(t *testing.T) {
|
func TestBrokerNoThreshold(t *testing.T) {
|
||||||
var alerts []models.Alert
|
var alerts []models.Alert
|
||||||
DefaultEmptyTicker = 50 * time.Millisecond
|
DefaultEmptyTicker = 50 * time.Millisecond
|
||||||
|
|
||||||
buildDummyPlugin()
|
buildDummyPlugin(t)
|
||||||
setPluginPermTo744()
|
setPluginPermTo744(t)
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
|
|
||||||
// init
|
// init
|
||||||
pluginCfg := csconfig.PluginCfg{}
|
pluginCfg := csconfig.PluginCfg{}
|
||||||
pb := PluginBroker{}
|
pb := PluginBroker{}
|
||||||
|
@ -300,49 +269,55 @@ func TestBrokerNoThreshold(t *testing.T) {
|
||||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||||
Notifications: []string{"dummy_default"},
|
Notifications: []string{"dummy_default"},
|
||||||
})
|
})
|
||||||
|
|
||||||
// default config
|
// default config
|
||||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||||
PluginDir: testPath,
|
PluginDir: testPath,
|
||||||
NotificationDir: "./tests/notifications",
|
NotificationDir: "./tests/notifications",
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
tomb := tomb.Tomb{}
|
tomb := tomb.Tomb{}
|
||||||
|
|
||||||
go pb.Run(&tomb)
|
go pb.Run(&tomb)
|
||||||
defer pb.Kill()
|
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{}}
|
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
// we expect one now
|
// we expect one now
|
||||||
content, err := os.ReadFile("./out")
|
content, err := os.ReadFile("./out")
|
||||||
if err != nil {
|
require.NoError(t, err, "Error reading file")
|
||||||
log.Errorf("Error reading file: %s", err)
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(content, &alerts)
|
err = json.Unmarshal(content, &alerts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(alerts))
|
assert.Len(t, alerts, 1)
|
||||||
|
|
||||||
// remove it
|
// remove it
|
||||||
os.Remove("./out")
|
os.Remove("./out")
|
||||||
|
|
||||||
// and another one
|
// and another one
|
||||||
log.Printf("second send")
|
log.Printf("second send")
|
||||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||||
time.Sleep(200 * time.Millisecond)
|
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")
|
content, err = os.ReadFile("./out")
|
||||||
if err != nil {
|
require.NoError(t, err, "Error reading file")
|
||||||
log.Errorf("Error reading file: %s", err)
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(content, &alerts)
|
err = json.Unmarshal(content, &alerts)
|
||||||
log.Printf("content-> %s", content)
|
log.Printf("content-> %s", content)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(alerts))
|
assert.Len(t, alerts, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
||||||
// test grouping by "time"
|
// test grouping by "time"
|
||||||
DefaultEmptyTicker = 50 * time.Millisecond
|
DefaultEmptyTicker = 50 * time.Millisecond
|
||||||
buildDummyPlugin()
|
buildDummyPlugin(t)
|
||||||
setPluginPermTo744()
|
setPluginPermTo744(t)
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
|
|
||||||
// init
|
// init
|
||||||
pluginCfg := csconfig.PluginCfg{}
|
pluginCfg := csconfig.PluginCfg{}
|
||||||
|
@ -362,6 +337,7 @@ func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
tomb := tomb.Tomb{}
|
tomb := tomb.Tomb{}
|
||||||
|
|
||||||
go pb.Run(&tomb)
|
go pb.Run(&tomb)
|
||||||
defer pb.Kill()
|
defer pb.Kill()
|
||||||
// send data
|
// send data
|
||||||
|
@ -375,21 +351,23 @@ func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
||||||
// after 1 seconds, we should have data
|
// after 1 seconds, we should have data
|
||||||
content, err := os.ReadFile("./out")
|
content, err := os.ReadFile("./out")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
var alerts []models.Alert
|
var alerts []models.Alert
|
||||||
err = json.Unmarshal(content, &alerts)
|
err = json.Unmarshal(content, &alerts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 3, len(alerts))
|
assert.Len(t, alerts, 3)
|
||||||
|
|
||||||
// restore config
|
// restore config
|
||||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
|
||||||
t.Fatalf("unable to write config file %s", err)
|
require.NoError(t, err,"unable to write config file")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
|
func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
|
||||||
DefaultEmptyTicker = 50 * time.Millisecond
|
DefaultEmptyTicker = 50 * time.Millisecond
|
||||||
buildDummyPlugin()
|
buildDummyPlugin(t)
|
||||||
setPluginPermTo744()
|
setPluginPermTo(t, "744")
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
|
|
||||||
// init
|
// init
|
||||||
pluginCfg := csconfig.PluginCfg{}
|
pluginCfg := csconfig.PluginCfg{}
|
||||||
pb := PluginBroker{}
|
pb := PluginBroker{}
|
||||||
|
@ -397,6 +375,7 @@ func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
|
||||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||||
Notifications: []string{"dummy_default"},
|
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")
|
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||||
cfg.GroupThreshold = 4
|
cfg.GroupThreshold = 4
|
||||||
|
@ -408,38 +387,42 @@ func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
tomb := tomb.Tomb{}
|
tomb := tomb.Tomb{}
|
||||||
|
|
||||||
go pb.Run(&tomb)
|
go pb.Run(&tomb)
|
||||||
defer pb.Kill()
|
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{}}
|
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)
|
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")
|
assert.NoFileExists(t, "./out")
|
||||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
// and now we should
|
// and now we should
|
||||||
content, err := os.ReadFile("./out")
|
content, err := os.ReadFile("./out")
|
||||||
if err != nil {
|
require.NoError(t, err, "Error reading file")
|
||||||
log.Errorf("Error reading file: %s", err)
|
|
||||||
}
|
|
||||||
var alerts []models.Alert
|
var alerts []models.Alert
|
||||||
err = json.Unmarshal(content, &alerts)
|
err = json.Unmarshal(content, &alerts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 4, len(alerts))
|
assert.Len(t, alerts, 4)
|
||||||
|
|
||||||
// restore config
|
// restore config
|
||||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
|
||||||
t.Fatalf("unable to write config file %s", err)
|
require.NoError(t, err,"unable to write config file")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBrokerRunGroupThreshold(t *testing.T) {
|
func TestBrokerRunGroupThreshold(t *testing.T) {
|
||||||
// test grouping by "size"
|
// test grouping by "size"
|
||||||
DefaultEmptyTicker = 50 * time.Millisecond
|
DefaultEmptyTicker = 50 * time.Millisecond
|
||||||
buildDummyPlugin()
|
buildDummyPlugin(t)
|
||||||
setPluginPermTo744()
|
setPluginPermTo(t, "744")
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
|
|
||||||
// init
|
// init
|
||||||
pluginCfg := csconfig.PluginCfg{}
|
pluginCfg := csconfig.PluginCfg{}
|
||||||
pb := PluginBroker{}
|
pb := PluginBroker{}
|
||||||
|
@ -447,6 +430,7 @@ func TestBrokerRunGroupThreshold(t *testing.T) {
|
||||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||||
Notifications: []string{"dummy_default"},
|
Notifications: []string{"dummy_default"},
|
||||||
})
|
})
|
||||||
|
|
||||||
// set groupwait
|
// set groupwait
|
||||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||||
cfg.GroupThreshold = 4
|
cfg.GroupThreshold = 4
|
||||||
|
@ -455,39 +439,44 @@ func TestBrokerRunGroupThreshold(t *testing.T) {
|
||||||
PluginDir: testPath,
|
PluginDir: testPath,
|
||||||
NotificationDir: "./tests/notifications",
|
NotificationDir: "./tests/notifications",
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
tomb := tomb.Tomb{}
|
tomb := tomb.Tomb{}
|
||||||
|
|
||||||
go pb.Run(&tomb)
|
go pb.Run(&tomb)
|
||||||
defer pb.Kill()
|
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{}}
|
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)
|
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")
|
assert.NoFileExists(t, "./out")
|
||||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
// and now we should
|
// and now we should
|
||||||
content, err := os.ReadFile("./out")
|
content, err := os.ReadFile("./out")
|
||||||
if err != nil {
|
require.NoError(t, err, "Error reading file")
|
||||||
log.Errorf("Error reading file: %s", err)
|
|
||||||
}
|
|
||||||
var alerts []models.Alert
|
var alerts []models.Alert
|
||||||
err = json.Unmarshal(content, &alerts)
|
err = json.Unmarshal(content, &alerts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 4, len(alerts))
|
assert.Len(t, alerts, 4)
|
||||||
|
|
||||||
// restore config
|
// restore config
|
||||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
|
||||||
t.Fatalf("unable to write config file %s", err)
|
require.NoError(t, err, "unable to write config file")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBrokerRunTimeThreshold(t *testing.T) {
|
func TestBrokerRunTimeThreshold(t *testing.T) {
|
||||||
DefaultEmptyTicker = 50 * time.Millisecond
|
DefaultEmptyTicker = 50 * time.Millisecond
|
||||||
buildDummyPlugin()
|
buildDummyPlugin(t)
|
||||||
setPluginPermTo744()
|
setPluginPermTo(t, "744")
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
|
|
||||||
// init
|
// init
|
||||||
pluginCfg := csconfig.PluginCfg{}
|
pluginCfg := csconfig.PluginCfg{}
|
||||||
pb := PluginBroker{}
|
pb := PluginBroker{}
|
||||||
|
@ -495,9 +484,10 @@ func TestBrokerRunTimeThreshold(t *testing.T) {
|
||||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||||
Notifications: []string{"dummy_default"},
|
Notifications: []string{"dummy_default"},
|
||||||
})
|
})
|
||||||
|
|
||||||
// set groupwait
|
// set groupwait
|
||||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
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")
|
writeconfig(t, cfg, "tests/notifications/dummy.yaml")
|
||||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||||
PluginDir: testPath,
|
PluginDir: testPath,
|
||||||
|
@ -505,34 +495,37 @@ func TestBrokerRunTimeThreshold(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
tomb := tomb.Tomb{}
|
tomb := tomb.Tomb{}
|
||||||
|
|
||||||
go pb.Run(&tomb)
|
go pb.Run(&tomb)
|
||||||
defer pb.Kill()
|
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{}}
|
||||||
time.Sleep(200 * time.Millisecond)
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
|
||||||
// we shouldn't have data yet
|
// we shouldn't have data yet
|
||||||
assert.NoFileExists(t, "./out")
|
assert.NoFileExists(t, "./out")
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
// and now we should
|
// and now we should
|
||||||
content, err := os.ReadFile("./out")
|
content, err := os.ReadFile("./out")
|
||||||
if err != nil {
|
require.NoError(t, err, "Error reading file")
|
||||||
log.Errorf("Error reading file: %s", err)
|
|
||||||
}
|
|
||||||
var alerts []models.Alert
|
var alerts []models.Alert
|
||||||
err = json.Unmarshal(content, &alerts)
|
err = json.Unmarshal(content, &alerts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(alerts))
|
assert.Len(t, alerts, 1)
|
||||||
|
|
||||||
// restore config
|
// restore config
|
||||||
if err := os.WriteFile("tests/notifications/dummy.yaml", raw, 0644); err != nil {
|
err = os.WriteFile("tests/notifications/dummy.yaml", raw, 0644)
|
||||||
t.Fatalf("unable to write config file %s", err)
|
require.NoError(t, err, "unable to write config file %s", err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBrokerRunSimple(t *testing.T) {
|
func TestBrokerRunSimple(t *testing.T) {
|
||||||
DefaultEmptyTicker = 50 * time.Millisecond
|
DefaultEmptyTicker = 50 * time.Millisecond
|
||||||
buildDummyPlugin()
|
buildDummyPlugin(t)
|
||||||
setPluginPermTo744()
|
setPluginPermTo(t, "744")
|
||||||
defer tearDown()
|
defer tearDown(t)
|
||||||
pluginCfg := csconfig.PluginCfg{}
|
pluginCfg := csconfig.PluginCfg{}
|
||||||
pb := PluginBroker{}
|
pb := PluginBroker{}
|
||||||
profiles := csconfig.NewDefaultConfig().API.Server.Profiles
|
profiles := csconfig.NewDefaultConfig().API.Server.Profiles
|
||||||
|
@ -545,10 +538,12 @@ func TestBrokerRunSimple(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
tomb := tomb.Tomb{}
|
tomb := tomb.Tomb{}
|
||||||
|
|
||||||
go pb.Run(&tomb)
|
go pb.Run(&tomb)
|
||||||
defer pb.Kill()
|
defer pb.Kill()
|
||||||
|
|
||||||
assert.NoFileExists(t, "./out")
|
assert.NoFileExists(t, "./out")
|
||||||
|
|
||||||
defer os.Remove("./out")
|
defer os.Remove("./out")
|
||||||
|
|
||||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||||
|
@ -556,62 +551,54 @@ func TestBrokerRunSimple(t *testing.T) {
|
||||||
time.Sleep(time.Millisecond * 200)
|
time.Sleep(time.Millisecond * 200)
|
||||||
|
|
||||||
content, err := os.ReadFile("./out")
|
content, err := os.ReadFile("./out")
|
||||||
if err != nil {
|
require.NoError(t, err, "Error reading file")
|
||||||
log.Errorf("Error reading file: %s", err)
|
|
||||||
}
|
|
||||||
var alerts []models.Alert
|
var alerts []models.Alert
|
||||||
err = json.Unmarshal(content, &alerts)
|
err = json.Unmarshal(content, &alerts)
|
||||||
assert.NoError(t, err)
|
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")
|
dir, err := os.MkdirTemp("./tests", "cs_plugin_test")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
cmd := exec.Command("go", "build", "-o", path.Join(dir, "notification-dummy"), "../../plugins/notifications/dummy/")
|
cmd := exec.Command("go", "build", "-o", path.Join(dir, "notification-dummy"), "../../plugins/notifications/dummy/")
|
||||||
if err := cmd.Run(); err != nil {
|
err = cmd.Run()
|
||||||
log.Fatal(err)
|
require.NoError(t, err, "while building dummy plugin")
|
||||||
}
|
|
||||||
testPath = dir
|
testPath = dir
|
||||||
os.Remove("./out")
|
os.Remove("./out")
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPluginPermTo(perm string) {
|
func setPluginPermTo(t *testing.T, perm string) {
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
if err := exec.Command("chmod", perm, path.Join(testPath, "notification-dummy")).Run(); err != nil {
|
err := exec.Command("chmod", perm, path.Join(testPath, "notification-dummy")).Run()
|
||||||
log.Fatal(errors.Wrapf(err, "chmod 744 %s", path.Join(testPath, "notification-dummy")))
|
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")
|
dir, err := os.MkdirTemp("./", "cs_plugin_test")
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
f, err := os.Create(path.Join(dir, "slack"))
|
f, err := os.Create(path.Join(dir, "slack"))
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
f.Close()
|
f.Close()
|
||||||
f, err = os.Create(path.Join(dir, "notification-gitter"))
|
f, err = os.Create(path.Join(dir, "notification-gitter"))
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
f.Close()
|
f.Close()
|
||||||
err = os.Mkdir(path.Join(dir, "dummy_dir"), 0666)
|
err = os.Mkdir(path.Join(dir, "dummy_dir"), 0666)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
testPath = dir
|
testPath = dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func tearDown() {
|
func tearDown(t *testing.T) {
|
||||||
err := os.RemoveAll(testPath)
|
err := os.RemoveAll(testPath)
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
os.Remove("./out")
|
os.Remove("./out")
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,13 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
|
||||||
"github.com/crowdsecurity/crowdsec/pkg/types"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"gopkg.in/tomb.v2"
|
"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",
|
name: "no plugin dir",
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
errContains: "The system cannot find the file specified.",
|
errContains: cstest.FileNotFoundMessage,
|
||||||
action: tearDown,
|
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