CI: refactoring pkg/csplugin tests (#2247)
This commit is contained in:
parent
f6544962ea
commit
12c32d507c
11 changed files with 449 additions and 550 deletions
2
go.mod
2
go.mod
|
@ -71,7 +71,7 @@ require (
|
|||
github.com/bluele/gcache v0.0.2
|
||||
github.com/cespare/xxhash/v2 v2.1.2
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/crowdsecurity/go-cs-lib v0.0.0-20230522120244-fa545c12e7ee
|
||||
github.com/crowdsecurity/go-cs-lib v0.0.0-20230531105801-4c1535c2b3bd
|
||||
github.com/goccy/go-yaml v1.9.7
|
||||
github.com/gofrs/uuid v4.0.0+incompatible
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -172,8 +172,8 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
|||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/crowdsecurity/dlog v0.0.0-20170105205344-4fb5f8204f26 h1:r97WNVC30Uen+7WnLs4xDScS/Ex988+id2k6mDf8psU=
|
||||
github.com/crowdsecurity/dlog v0.0.0-20170105205344-4fb5f8204f26/go.mod h1:zpv7r+7KXwgVUZnUNjyP22zc/D7LKjyoY02weH2RBbk=
|
||||
github.com/crowdsecurity/go-cs-lib v0.0.0-20230522120244-fa545c12e7ee h1:YD/SYJ0otjlyAxuLRzJNXTQyXcpccefTvaHextBT9mQ=
|
||||
github.com/crowdsecurity/go-cs-lib v0.0.0-20230522120244-fa545c12e7ee/go.mod h1:9JJLSpGj1ZXnROV3xAcJvS/HTaUvuA8K3gGOpO4tfVc=
|
||||
github.com/crowdsecurity/go-cs-lib v0.0.0-20230531105801-4c1535c2b3bd h1:Y70ceDKAKYFXTnxEjXuBDSh07umvDhbX3PCCYhdtsZ0=
|
||||
github.com/crowdsecurity/go-cs-lib v0.0.0-20230531105801-4c1535c2b3bd/go.mod h1:9JJLSpGj1ZXnROV3xAcJvS/HTaUvuA8K3gGOpO4tfVc=
|
||||
github.com/crowdsecurity/grokky v0.2.1 h1:t4VYnDlAd0RjDM2SlILalbwfCrQxtJSMGdQOR0zwkE4=
|
||||
github.com/crowdsecurity/grokky v0.2.1/go.mod h1:33usDIYzGDsgX1kHAThCbseso6JuWNJXOzRQDGXHtWM=
|
||||
github.com/crowdsecurity/machineid v1.0.2 h1:wpkpsUghJF8Khtmn/tg6GxgdhLA1Xflerh5lirI+bdc=
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
|
@ -375,22 +374,6 @@ func setRequiredFields(pluginCfg *PluginConfig) {
|
|||
|
||||
}
|
||||
|
||||
// helper which gives paths to all files in the given directory non-recursively
|
||||
func listFilesAtPath(path string) ([]string, error) {
|
||||
filePaths := make([]string, 0)
|
||||
files, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
continue
|
||||
}
|
||||
filePaths = append(filePaths, filepath.Join(path, file.Name()))
|
||||
}
|
||||
return filePaths, nil
|
||||
}
|
||||
|
||||
func getUUID() (string, error) {
|
||||
uuidv4, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
|
|
164
pkg/csplugin/broker_suite_test.go
Normal file
164
pkg/csplugin/broker_suite_test.go
Normal file
|
@ -0,0 +1,164 @@
|
|||
package csplugin
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
)
|
||||
|
||||
|
||||
type PluginSuite struct {
|
||||
suite.Suite
|
||||
|
||||
// where the plugin is built - temporary directory for the suite
|
||||
buildDir string
|
||||
// full path to the built plugin binary
|
||||
builtBinary string
|
||||
|
||||
runDir string // temporary directory for each test
|
||||
pluginDir string // (config_paths.plugin_dir)
|
||||
notifDir string // (config_paths.notification_dir)
|
||||
pluginBinary string // full path to the plugin binary (unique for each test)
|
||||
pluginConfig string // full path to the notification config (unique for each test)
|
||||
|
||||
pluginBroker *PluginBroker
|
||||
}
|
||||
|
||||
|
||||
func TestPluginSuite(t *testing.T) {
|
||||
suite.Run(t, new(PluginSuite))
|
||||
}
|
||||
|
||||
|
||||
func (s *PluginSuite) SetupSuite() {
|
||||
var err error
|
||||
|
||||
t := s.T()
|
||||
|
||||
s.buildDir, err = os.MkdirTemp("", "cs_plugin_test_build")
|
||||
require.NoError(t, err)
|
||||
|
||||
s.builtBinary = path.Join(s.buildDir, "notification-dummy")
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
s.builtBinary += ".exe"
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", "build", "-o", s.builtBinary, "../../plugins/notifications/dummy/")
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err, "while building dummy plugin")
|
||||
}
|
||||
|
||||
|
||||
func (s *PluginSuite) TearDownSuite() {
|
||||
t := s.T()
|
||||
err := os.RemoveAll(s.buildDir)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
||||
func copyFile(src string, dst string) error {
|
||||
s, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
d, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer d.Close()
|
||||
|
||||
_, err = io.Copy(d, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = d.Sync()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PluginSuite) SetupTest() {
|
||||
s.SetupSubTest()
|
||||
}
|
||||
|
||||
func (s *PluginSuite) TearDownTest() {
|
||||
s.TearDownSubTest()
|
||||
}
|
||||
|
||||
|
||||
func (s *PluginSuite) SetupSubTest() {
|
||||
var err error
|
||||
t := s.T()
|
||||
|
||||
s.runDir, err = os.MkdirTemp("", "cs_plugin_test")
|
||||
require.NoError(t, err)
|
||||
|
||||
s.pluginDir = path.Join(s.runDir, "bin")
|
||||
err = os.MkdirAll(path.Join(s.runDir, "bin"), 0o755)
|
||||
require.NoError(t, err, "while creating bin dir")
|
||||
|
||||
s.notifDir = path.Join(s.runDir, "config")
|
||||
err = os.MkdirAll(s.notifDir, 0o755)
|
||||
require.NoError(t, err, "while creating config dir")
|
||||
|
||||
s.pluginBinary = path.Join(s.pluginDir, "notification-dummy")
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
s.pluginBinary += ".exe"
|
||||
}
|
||||
|
||||
err = copyFile(s.builtBinary, s.pluginBinary)
|
||||
require.NoError(t, err, "while copying built binary")
|
||||
err = os.Chmod(s.pluginBinary, 0o744)
|
||||
require.NoError(t, err, "chmod 0744 %s", s.pluginBinary)
|
||||
|
||||
s.pluginConfig = path.Join(s.notifDir, "dummy.yaml")
|
||||
err = copyFile("testdata/dummy.yaml", s.pluginConfig)
|
||||
require.NoError(t, err, "while copying plugin config")
|
||||
}
|
||||
|
||||
func (s *PluginSuite) TearDownSubTest() {
|
||||
t := s.T()
|
||||
if s.pluginBroker != nil {
|
||||
s.pluginBroker.Kill()
|
||||
s.pluginBroker = nil
|
||||
}
|
||||
|
||||
err := os.RemoveAll(s.runDir)
|
||||
if runtime.GOOS != "windows" {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
os.Remove("./out")
|
||||
}
|
||||
|
||||
func (s *PluginSuite) InitBroker(procCfg *csconfig.PluginCfg) (*PluginBroker, error) {
|
||||
pb := PluginBroker{}
|
||||
if procCfg == nil {
|
||||
procCfg = &csconfig.PluginCfg{}
|
||||
}
|
||||
profiles := csconfig.NewDefaultConfig().API.Server.Profiles
|
||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||
Notifications: []string{"dummy_default"},
|
||||
})
|
||||
err := pb.Init(procCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: s.pluginDir,
|
||||
NotificationDir: s.notifDir,
|
||||
})
|
||||
s.pluginBroker = &pb
|
||||
return s.pluginBroker, err
|
||||
}
|
|
@ -5,11 +5,6 @@ package csplugin
|
|||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -25,116 +20,39 @@ import (
|
|||
"github.com/crowdsecurity/crowdsec/pkg/models"
|
||||
)
|
||||
|
||||
var testPath string
|
||||
|
||||
func setPluginPermTo744(t *testing.T) {
|
||||
setPluginPermTo(t, "744")
|
||||
}
|
||||
|
||||
func setPluginPermTo722(t *testing.T) {
|
||||
setPluginPermTo(t, "722")
|
||||
}
|
||||
|
||||
func setPluginPermTo724(t *testing.T) {
|
||||
setPluginPermTo(t, "724")
|
||||
}
|
||||
func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||
setUp(t)
|
||||
defer tearDown(t)
|
||||
type args struct {
|
||||
path string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
want1 string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "valid plugin name, single dash",
|
||||
args: args{
|
||||
path: path.Join(testPath, "notification-gitter"),
|
||||
},
|
||||
want: "notification",
|
||||
want1: "gitter",
|
||||
},
|
||||
{
|
||||
name: "invalid plugin name",
|
||||
args: args{
|
||||
path: "./tests/gitter",
|
||||
},
|
||||
expectedErr: "plugin name ./tests/gitter is invalid. Name should be like {type-name}",
|
||||
},
|
||||
{
|
||||
name: "valid plugin name, multiple dash",
|
||||
args: args{
|
||||
path: "./tests/notification-instant-slack",
|
||||
},
|
||||
want: "notification-instant",
|
||||
want1: "slack",
|
||||
},
|
||||
}
|
||||
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 (s *PluginSuite) permissionSetter(perm os.FileMode) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
err := os.Chmod(s.pluginBinary, perm)
|
||||
require.NoError(t, err, "chmod %s %s", perm, s.pluginBinary)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListFilesAtPath(t *testing.T) {
|
||||
setUp(t)
|
||||
defer tearDown(t)
|
||||
type args struct {
|
||||
path string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "valid directory",
|
||||
args: args{
|
||||
path: testPath,
|
||||
},
|
||||
want: []string{
|
||||
filepath.Join(testPath, "notification-gitter"),
|
||||
filepath.Join(testPath, "slack"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid directory",
|
||||
args: args{
|
||||
path: "./foo/bar/",
|
||||
},
|
||||
expectedErr: "open ./foo/bar/: " + cstest.FileNotFoundMessage,
|
||||
},
|
||||
}
|
||||
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)
|
||||
func (s *PluginSuite) readconfig() (PluginConfig) {
|
||||
var config PluginConfig
|
||||
t := s.T()
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("listFilesAtPath() = %v, want %v", got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
orig, err := os.ReadFile(s.pluginConfig)
|
||||
require.NoError(t, err,"unable to read config file %s", s.pluginConfig)
|
||||
|
||||
err = yaml.Unmarshal(orig, &config)
|
||||
require.NoError(t, err,"unable to unmarshal config file")
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func TestBrokerInit(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("Skipping test on windows")
|
||||
|
||||
func (s *PluginSuite) writeconfig(config PluginConfig) {
|
||||
t := s.T()
|
||||
data, err := yaml.Marshal(&config)
|
||||
require.NoError(t, err,"unable to marshal config file")
|
||||
|
||||
err = os.WriteFile(s.pluginConfig, data, 0644)
|
||||
require.NoError(t, err,"unable to write config file %s", s.pluginConfig)
|
||||
}
|
||||
|
||||
|
||||
func (s *PluginSuite) TestBrokerInit() {
|
||||
tests := []struct {
|
||||
name string
|
||||
action func(*testing.T)
|
||||
|
@ -143,28 +61,30 @@ func TestBrokerInit(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "valid config",
|
||||
action: setPluginPermTo744,
|
||||
},
|
||||
{
|
||||
name: "group writable binary",
|
||||
expectedErr: "notification-dummy is world writable",
|
||||
action: setPluginPermTo722,
|
||||
action: s.permissionSetter(0o722),
|
||||
},
|
||||
{
|
||||
name: "group writable binary",
|
||||
expectedErr: "notification-dummy is group writable",
|
||||
action: setPluginPermTo724,
|
||||
action: s.permissionSetter(0o724),
|
||||
},
|
||||
{
|
||||
name: "no plugin dir",
|
||||
expectedErr: cstest.FileNotFoundMessage,
|
||||
action: tearDown,
|
||||
action: func(t *testing.T) {
|
||||
err := os.RemoveAll(s.runDir)
|
||||
require.NoError(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no plugin binary",
|
||||
expectedErr: "binary for plugin dummy_default not found",
|
||||
action: func(t *testing.T) {
|
||||
err := os.Remove(path.Join(testPath, "notification-dummy"))
|
||||
err := os.Remove(s.pluginBinary)
|
||||
require.NoError(t, err)
|
||||
},
|
||||
},
|
||||
|
@ -174,7 +94,6 @@ func TestBrokerInit(t *testing.T) {
|
|||
procCfg: csconfig.PluginCfg{
|
||||
User: "123445555551122toto",
|
||||
},
|
||||
action: setPluginPermTo744,
|
||||
},
|
||||
{
|
||||
name: "only specify group",
|
||||
|
@ -182,7 +101,6 @@ func TestBrokerInit(t *testing.T) {
|
|||
procCfg: csconfig.PluginCfg{
|
||||
Group: "123445555551122toto",
|
||||
},
|
||||
action: setPluginPermTo744,
|
||||
},
|
||||
{
|
||||
name: "Fails to run as root",
|
||||
|
@ -191,7 +109,6 @@ func TestBrokerInit(t *testing.T) {
|
|||
User: "root",
|
||||
Group: "root",
|
||||
},
|
||||
action: setPluginPermTo744,
|
||||
},
|
||||
{
|
||||
name: "Invalid user and group",
|
||||
|
@ -200,7 +117,6 @@ func TestBrokerInit(t *testing.T) {
|
|||
User: "toto1234",
|
||||
Group: "toto1234",
|
||||
},
|
||||
action: setPluginPermTo744,
|
||||
},
|
||||
{
|
||||
name: "Valid user and invalid group",
|
||||
|
@ -209,79 +125,33 @@ func TestBrokerInit(t *testing.T) {
|
|||
User: "nobody",
|
||||
Group: "toto1234",
|
||||
},
|
||||
action: setPluginPermTo744,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
defer tearDown(t)
|
||||
buildDummyPlugin(t)
|
||||
s.Run(tc.name, func() {
|
||||
t := s.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(&tc.procCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
defer pb.Kill()
|
||||
_, err := s.InitBroker(&tc.procCfg)
|
||||
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func readconfig(t *testing.T, path string) ([]byte, PluginConfig) {
|
||||
var config PluginConfig
|
||||
orig, err := os.ReadFile("tests/notifications/dummy.yaml")
|
||||
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)
|
||||
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) {
|
||||
func (s *PluginSuite) TestBrokerNoThreshold() {
|
||||
var alerts []models.Alert
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
|
||||
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
|
||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
t := s.T()
|
||||
|
||||
pb, err := s.InitBroker(nil)
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
|
||||
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{}}
|
||||
|
@ -292,7 +162,7 @@ func TestBrokerNoThreshold(t *testing.T) {
|
|||
require.NoError(t, err, "Error reading file")
|
||||
|
||||
err = json.Unmarshal(content, &alerts)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, alerts, 1)
|
||||
|
||||
// remove it
|
||||
|
@ -313,34 +183,24 @@ func TestBrokerNoThreshold(t *testing.T) {
|
|||
assert.Len(t, alerts, 1)
|
||||
}
|
||||
|
||||
func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
||||
func (s *PluginSuite) TestBrokerRunGroupAndTimeThreshold_TimeFirst() {
|
||||
// test grouping by "time"
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
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"},
|
||||
})
|
||||
t := s.T()
|
||||
|
||||
// set groupwait and groupthreshold, should honor whichever comes first
|
||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||
cfg := s.readconfig()
|
||||
cfg.GroupThreshold = 4
|
||||
cfg.GroupWait = 1 * time.Second
|
||||
writeconfig(t, cfg, "tests/notifications/dummy.yaml")
|
||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
s.writeconfig(cfg)
|
||||
|
||||
pb, err := s.InitBroker(nil)
|
||||
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{}}
|
||||
|
@ -357,40 +217,24 @@ func TestBrokerRunGroupAndTimeThreshold_TimeFirst(t *testing.T) {
|
|||
err = json.Unmarshal(content, &alerts)
|
||||
assert.NoError(t, 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) {
|
||||
func (s *PluginSuite) TestBrokerRunGroupAndTimeThreshold_CountFirst() {
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
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"},
|
||||
})
|
||||
t := s.T()
|
||||
|
||||
// set groupwait and groupthreshold, should honor whichever comes first
|
||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||
cfg := s.readconfig()
|
||||
cfg.GroupThreshold = 4
|
||||
cfg.GroupWait = 4 * time.Second
|
||||
writeconfig(t, cfg, "tests/notifications/dummy.yaml")
|
||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
s.writeconfig(cfg)
|
||||
|
||||
pb, err := s.InitBroker(nil)
|
||||
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{}}
|
||||
|
@ -411,41 +255,24 @@ func TestBrokerRunGroupAndTimeThreshold_CountFirst(t *testing.T) {
|
|||
err = json.Unmarshal(content, &alerts)
|
||||
assert.NoError(t, 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) {
|
||||
func (s *PluginSuite) TestBrokerRunGroupThreshold() {
|
||||
// test grouping by "size"
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
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"},
|
||||
})
|
||||
t := s.T()
|
||||
|
||||
// set groupwait
|
||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||
cfg := s.readconfig()
|
||||
cfg.GroupThreshold = 4
|
||||
writeconfig(t, cfg, "tests/notifications/dummy.yaml")
|
||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
s.writeconfig(cfg)
|
||||
|
||||
pb, err := s.InitBroker(nil)
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
|
||||
tomb := tomb.Tomb{}
|
||||
go pb.Run(&tomb)
|
||||
defer pb.Kill()
|
||||
|
||||
// send data
|
||||
pb.PluginChannel <- ProfileAlert{ProfileID: uint(0), Alert: &models.Alert{}}
|
||||
|
@ -466,39 +293,23 @@ func TestBrokerRunGroupThreshold(t *testing.T) {
|
|||
err = json.Unmarshal(content, &alerts)
|
||||
assert.NoError(t, 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) {
|
||||
func (s *PluginSuite) TestBrokerRunTimeThreshold() {
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
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"},
|
||||
})
|
||||
t := s.T()
|
||||
|
||||
// set groupwait
|
||||
raw, cfg := readconfig(t, "tests/notifications/dummy.yaml")
|
||||
cfg := s.readconfig()
|
||||
cfg.GroupWait = 1 * time.Second
|
||||
writeconfig(t, cfg, "tests/notifications/dummy.yaml")
|
||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
s.writeconfig(cfg)
|
||||
|
||||
pb, err := s.InitBroker(nil)
|
||||
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{}}
|
||||
|
@ -516,32 +327,18 @@ func TestBrokerRunTimeThreshold(t *testing.T) {
|
|||
err = json.Unmarshal(content, &alerts)
|
||||
assert.NoError(t, 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) {
|
||||
func (s *PluginSuite) TestBrokerRunSimple() {
|
||||
DefaultEmptyTicker = 50 * time.Millisecond
|
||||
buildDummyPlugin(t)
|
||||
setPluginPermTo(t, "744")
|
||||
defer tearDown(t)
|
||||
pluginCfg := csconfig.PluginCfg{}
|
||||
pb := PluginBroker{}
|
||||
profiles := csconfig.NewDefaultConfig().API.Server.Profiles
|
||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||
Notifications: []string{"dummy_default"},
|
||||
})
|
||||
err := pb.Init(&pluginCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
tomb := tomb.Tomb{}
|
||||
|
||||
t := s.T()
|
||||
|
||||
pb, err := s.InitBroker(nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
tomb := tomb.Tomb{}
|
||||
go pb.Run(&tomb)
|
||||
defer pb.Kill()
|
||||
|
||||
assert.NoFileExists(t, "./out")
|
||||
|
||||
|
@ -559,47 +356,3 @@ func TestBrokerRunSimple(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Len(t, alerts, 2)
|
||||
}
|
||||
|
||||
func buildDummyPlugin(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("./tests", "cs_plugin_test")
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd := exec.Command("go", "build", "-o", path.Join(dir, "notification-dummy"), "../../plugins/notifications/dummy/")
|
||||
err = cmd.Run()
|
||||
require.NoError(t, err, "while building dummy plugin")
|
||||
|
||||
testPath = dir
|
||||
os.Remove("./out")
|
||||
}
|
||||
|
||||
func setPluginPermTo(t *testing.T, perm string) {
|
||||
if runtime.GOOS != "windows" {
|
||||
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(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("./", "cs_plugin_test")
|
||||
require.NoError(t, err)
|
||||
|
||||
f, err := os.Create(path.Join(dir, "slack"))
|
||||
require.NoError(t, err)
|
||||
|
||||
f.Close()
|
||||
f, err = os.Create(path.Join(dir, "notification-gitter"))
|
||||
require.NoError(t, err)
|
||||
|
||||
f.Close()
|
||||
err = os.Mkdir(path.Join(dir, "dummy_dir"), 0666)
|
||||
require.NoError(t, err)
|
||||
|
||||
testPath = dir
|
||||
}
|
||||
|
||||
func tearDown(t *testing.T) {
|
||||
err := os.RemoveAll(testPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
os.Remove("./out")
|
||||
}
|
||||
|
|
|
@ -3,16 +3,12 @@
|
|||
package csplugin
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/tomb.v2"
|
||||
|
||||
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
|
||||
|
@ -27,188 +23,55 @@ Due to the complexity of file permission modification with go on windows, we onl
|
|||
not if it will actually reject plugins with invalid permissions
|
||||
*/
|
||||
|
||||
var testPath string
|
||||
|
||||
func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||
setUp()
|
||||
defer tearDown()
|
||||
type args struct {
|
||||
path string
|
||||
}
|
||||
func (s *PluginSuite) TestBrokerInit() {
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
want1 string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid plugin name, single dash",
|
||||
args: args{
|
||||
path: path.Join(testPath, "notification-gitter"),
|
||||
},
|
||||
want: "notification",
|
||||
want1: "gitter",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid plugin name",
|
||||
args: args{
|
||||
path: ".\\tests\\gitter.exe",
|
||||
},
|
||||
want: "",
|
||||
want1: "",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid plugin name, multiple dash",
|
||||
args: args{
|
||||
path: ".\\tests\\notification-instant-slack.exe",
|
||||
},
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListFilesAtPath(t *testing.T) {
|
||||
setUp()
|
||||
defer tearDown()
|
||||
type args struct {
|
||||
path string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid directory",
|
||||
args: args{
|
||||
path: testPath,
|
||||
},
|
||||
want: []string{
|
||||
filepath.Join(testPath, "notification-gitter"),
|
||||
filepath.Join(testPath, "slack"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid directory",
|
||||
args: args{
|
||||
path: "./foo/bar/",
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "no plugin dir",
|
||||
wantErr: true,
|
||||
errContains: cstest.FileNotFoundMessage,
|
||||
action: tearDown,
|
||||
expectedErr: cstest.PathNotFoundMessage,
|
||||
action: func(t *testing.T) {
|
||||
err := os.RemoveAll(s.runDir)
|
||||
require.NoError(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no plugin binary",
|
||||
wantErr: true,
|
||||
errContains: "binary for plugin dummy_default not found",
|
||||
action: func() {
|
||||
err := os.Remove(path.Join(testPath, "notification-dummy.exe"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expectedErr: "binary for plugin dummy_default not found",
|
||||
action: func(t *testing.T) {
|
||||
err := os.Remove(s.pluginBinary)
|
||||
require.NoError(t, err)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
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
|
||||
s.Run(tc.name, func() {
|
||||
t := s.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{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
defer pb.Kill()
|
||||
if test.wantErr {
|
||||
assert.ErrorContains(t, err, test.errContains)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
_, err := s.InitBroker(&tc.procCfg)
|
||||
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBrokerRun(t *testing.T) {
|
||||
buildDummyPlugin()
|
||||
defer tearDown()
|
||||
procCfg := csconfig.PluginCfg{}
|
||||
pb := PluginBroker{}
|
||||
profiles := csconfig.NewDefaultConfig().API.Server.Profiles
|
||||
profiles = append(profiles, &csconfig.ProfileCfg{
|
||||
Notifications: []string{"dummy_default"},
|
||||
})
|
||||
err := pb.Init(&procCfg, profiles, &csconfig.ConfigurationPaths{
|
||||
PluginDir: testPath,
|
||||
NotificationDir: "./tests/notifications",
|
||||
})
|
||||
func (s *PluginSuite) TestBrokerRun() {
|
||||
t := s.T()
|
||||
|
||||
pb, err := s.InitBroker(nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
tomb := tomb.Tomb{}
|
||||
go pb.Run(&tomb)
|
||||
defer pb.Kill()
|
||||
|
||||
assert.NoFileExists(t, "./out")
|
||||
defer os.Remove("./out")
|
||||
|
@ -220,44 +83,3 @@ func TestBrokerRun(t *testing.T) {
|
|||
assert.FileExists(t, ".\\out")
|
||||
assert.Equal(t, types.GetLineCountForFile(".\\out"), 2)
|
||||
}
|
||||
|
||||
func buildDummyPlugin() {
|
||||
dir, err := os.MkdirTemp(".\\tests", "cs_plugin_test")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd := exec.Command("go", "build", "-o", path.Join(dir, "notification-dummy.exe"), "../../plugins/notifications/dummy/")
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
testPath = dir
|
||||
}
|
||||
|
||||
func setUp() {
|
||||
dir, err := os.MkdirTemp("./", "cs_plugin_test")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
f, err := os.Create(path.Join(dir, "slack"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
f, err = os.Create(path.Join(dir, "notification-gitter"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
f.Close()
|
||||
err = os.Mkdir(path.Join(dir, "dummy_dir"), 0666)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
testPath = dir
|
||||
}
|
||||
|
||||
func tearDown() {
|
||||
err := os.RemoveAll(testPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
22
pkg/csplugin/listfiles.go
Normal file
22
pkg/csplugin/listfiles.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package csplugin
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// helper which gives paths to all files in the given directory non-recursively
|
||||
func listFilesAtPath(path string) ([]string, error) {
|
||||
filePaths := make([]string, 0)
|
||||
files, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, file := range files {
|
||||
if ! file.IsDir() {
|
||||
filePaths = append(filePaths, filepath.Join(path, file.Name()))
|
||||
}
|
||||
}
|
||||
return filePaths, nil
|
||||
}
|
||||
|
57
pkg/csplugin/listfiles_test.go
Normal file
57
pkg/csplugin/listfiles_test.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package csplugin
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
|
||||
)
|
||||
|
||||
func TestListFilesAtPath(t *testing.T) {
|
||||
dir, err := os.MkdirTemp("", "test-listfiles")
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
os.RemoveAll(dir)
|
||||
})
|
||||
_, err = os.Create(filepath.Join(dir, "notification-gitter"))
|
||||
require.NoError(t, err)
|
||||
_, err = os.Create(filepath.Join(dir, "slack"))
|
||||
require.NoError(t, err)
|
||||
err = os.Mkdir(filepath.Join(dir, "somedir"), 0755)
|
||||
require.NoError(t, err)
|
||||
_, err = os.Create(filepath.Join(dir, "somedir", "inner"))
|
||||
require.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
want []string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "valid directory",
|
||||
path: dir,
|
||||
want: []string{
|
||||
filepath.Join(dir, "notification-gitter"),
|
||||
filepath.Join(dir, "slack"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid directory",
|
||||
path: "./foo/bar/",
|
||||
expectedErr: "open ./foo/bar/: " + cstest.PathNotFoundMessage,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got, err := listFilesAtPath(tc.path)
|
||||
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||
assert.ElementsMatch(t, tc.want, got)
|
||||
})
|
||||
}
|
||||
}
|
49
pkg/csplugin/utils_test.go
Normal file
49
pkg/csplugin/utils_test.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
//go:build linux || freebsd || netbsd || openbsd || solaris || !windows
|
||||
|
||||
package csplugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
|
||||
)
|
||||
|
||||
func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
want string
|
||||
want1 string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "valid plugin name, single dash",
|
||||
path: "/path/to/notification-gitter",
|
||||
want: "notification",
|
||||
want1: "gitter",
|
||||
},
|
||||
{
|
||||
name: "invalid plugin name",
|
||||
path: "/path/to/gitter",
|
||||
expectedErr: "plugin name /path/to/gitter is invalid. Name should be like {type-name}",
|
||||
},
|
||||
{
|
||||
name: "valid plugin name, multiple dash",
|
||||
path: "/path/to/notification-instant-slack",
|
||||
want: "notification-instant",
|
||||
want1: "slack",
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got, got1, err := getPluginTypeAndSubtypeFromPath(tc.path)
|
||||
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||
|
||||
assert.Equal(t, tc.want, got)
|
||||
assert.Equal(t, tc.want1, got1)
|
||||
})
|
||||
}
|
||||
}
|
49
pkg/csplugin/utils_windows_test.go
Normal file
49
pkg/csplugin/utils_windows_test.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
//go:build windows
|
||||
|
||||
package csplugin
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/crowdsecurity/go-cs-lib/pkg/cstest"
|
||||
)
|
||||
|
||||
func TestGetPluginNameAndTypeFromPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
want string
|
||||
want1 string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "valid plugin name, single dash",
|
||||
path: "c:\\path\\to\\notification-gitter",
|
||||
want: "notification",
|
||||
want1: "gitter",
|
||||
},
|
||||
{
|
||||
name: "invalid plugin name",
|
||||
path: "c:\\path\\to\\gitter.exe",
|
||||
expectedErr: "plugin name c:\\path\\to\\gitter.exe is invalid. Name should be like {type-name}",
|
||||
},
|
||||
{
|
||||
name: "valid plugin name, multiple dash",
|
||||
path: "c:\\path\\to\\notification-instant-slack.exe",
|
||||
want: "notification-instant",
|
||||
want1: "slack",
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got, got1, err := getPluginTypeAndSubtypeFromPath(tc.path)
|
||||
cstest.RequireErrorContains(t, err, tc.expectedErr)
|
||||
|
||||
assert.Equal(t, tc.want, got)
|
||||
assert.Equal(t, tc.want1, got1)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue