local api (#482)

Co-authored-by: AlteredCoder
Co-authored-by: erenJag
This commit is contained in:
Thibault "bui" Koechlin 2020-11-30 10:37:17 +01:00 committed by GitHub
parent 5f339ab312
commit dbb420f79e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
563 changed files with 64363 additions and 10714 deletions

View file

@ -1,43 +1,199 @@
package csconfig
import (
"flag"
"os"
"fmt"
"strings"
"testing"
"github.com/crowdsecurity/crowdsec/pkg/outputs"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
func TestDefaultConfig(t *testing.T) {
x := NewDefaultConfig()
x.Dump()
}
func TestNormalLoad(t *testing.T) {
x := NewConfig()
err := x.LoadConfigurationFile("./tests/config.yaml")
if err != nil {
t.Fatalf("unexpected error %s", err)
}
x = NewConfig()
err = x.LoadConfigurationFile("./tests/xxx.yaml")
if fmt.Sprintf("%s", err) != "failed to read config file: open ./tests/xxx.yaml: no such file or directory" {
t.Fatalf("unexpected error %s", err)
}
x = NewConfig()
err = x.LoadConfigurationFile("./tests/simulation.yaml")
if !strings.HasPrefix(fmt.Sprintf("%s", err), "failed unmarshaling config: yaml: unmarshal error") {
t.Fatalf("unexpected error %s", err)
}
}
func TestCleanupPaths(t *testing.T) {
tests := []struct {
name string
Input *GlobalConfig
expectedResult *GlobalConfig
err string
}{
{
name: "daemon cleanup",
Input: &GlobalConfig{
Common: &CommonCfg{
PidDir: "////tmp//",
LogDir: "/////tmp///",
WorkingDir: "/////tmp///",
},
},
expectedResult: &GlobalConfig{
Common: &CommonCfg{
PidDir: "/tmp",
LogDir: "/tmp",
WorkingDir: "/tmp",
},
},
},
//
{
name: "crowdsec cleanup",
Input: &GlobalConfig{
Crowdsec: &CrowdsecServiceCfg{
AcquisitionFilePath: "////tmp//x.yaml",
},
},
expectedResult: &GlobalConfig{
Crowdsec: &CrowdsecServiceCfg{
AcquisitionFilePath: "/tmp/x.yaml",
},
},
},
//
{
name: "config paths cleanup",
Input: &GlobalConfig{
ConfigPaths: &ConfigurationPaths{
HubDir: "////tmp//",
HubIndexFile: "////tmp//x.yaml",
ConfigDir: "////tmp//",
DataDir: "////tmp//",
SimulationFilePath: "//tmp///toto.yaml",
},
},
expectedResult: &GlobalConfig{
ConfigPaths: &ConfigurationPaths{
HubDir: "/tmp",
HubIndexFile: "/tmp/x.yaml",
ConfigDir: "/tmp",
DataDir: "/tmp",
SimulationFilePath: "/tmp/toto.yaml",
},
},
},
}
for idx, test := range tests {
err := test.Input.CleanupPaths()
if test.err != "" {
if strings.HasPrefix(fmt.Sprintf("%s", err), test.err) {
t.Fatalf("%d/%d expected err %s got %s", idx, len(tests), test.err, fmt.Sprintf("%s", err))
}
}
isOk := assert.Equal(t, test.expectedResult, test.Input)
if !isOk {
t.Fatalf("%d/%d failed test", idx, len(tests))
}
}
}
func TestSimulationLoading(t *testing.T) {
tests := []struct {
name string
Input *GlobalConfig
expectedResult *SimulationConfig
err string
}{
{
name: "basic valid simulation",
Input: &GlobalConfig{
ConfigPaths: &ConfigurationPaths{
SimulationFilePath: "./tests/simulation.yaml",
},
Crowdsec: &CrowdsecServiceCfg{},
},
expectedResult: &SimulationConfig{Simulation: new(bool)},
},
{
name: "basic bad file name",
Input: &GlobalConfig{
ConfigPaths: &ConfigurationPaths{
SimulationFilePath: "./tests/xxx.yaml",
},
Crowdsec: &CrowdsecServiceCfg{},
},
err: "while reading './tests/xxx.yaml': open ./tests/xxx.yaml: no such file or directory",
},
{
name: "basic nil config",
Input: &GlobalConfig{
ConfigPaths: &ConfigurationPaths{
SimulationFilePath: "",
},
Crowdsec: &CrowdsecServiceCfg{},
},
},
{
name: "basic bad file content",
Input: &GlobalConfig{
ConfigPaths: &ConfigurationPaths{
SimulationFilePath: "./tests/config.yaml",
},
Crowdsec: &CrowdsecServiceCfg{},
},
err: "while unmarshaling simulation file './tests/config.yaml' : yaml: unmarshal errors",
},
}
for idx, test := range tests {
err := test.Input.LoadSimulation()
if err == nil && test.err != "" {
t.Fatalf("%d/%d expected error, didn't get it", idx, len(tests))
} else if test.err != "" {
if !strings.HasPrefix(fmt.Sprintf("%s", err), test.err) {
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' failed", test.name)
}
}
}
func TestNewCrowdSecConfig(t *testing.T) {
tests := []struct {
name string
expectedResult *CrowdSec
expectedResult *GlobalConfig
err string
}{
{
name: "new configuration: basic",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: false,
Profiling: false,
WorkingFolder: "/tmp/",
DataFolder: "/var/lib/crowdsec/data/",
ConfigFolder: "/etc/crowdsec/config/",
PIDFolder: "/var/run/",
LogFolder: "/var/log/",
LogMode: "stdout",
APIMode: false,
NbParsers: 1,
Prometheus: false,
HTTPListen: "127.0.0.1:6060",
},
err: "",
name: "new configuration: basic",
expectedResult: &GlobalConfig{},
err: "",
},
}
for _, test := range tests {
result := NewCrowdSecConfig()
result := NewConfig()
isOk := assert.Equal(t, test.expectedResult, result)
if !isOk {
t.Fatalf("test '%s' failed", test.name)
@ -46,366 +202,3 @@ func TestNewCrowdSecConfig(t *testing.T) {
}
}
func TestLoadConfig(t *testing.T) {
tests := []struct {
name string
expectedResult *CrowdSec
Args []string
err string
}{
{
name: "load configuration: basic",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: true,
Profiling: true,
WorkingFolder: "./tests/",
DataFolder: "./tests/",
ConfigFolder: "./tests/",
PIDFolder: "./tests/",
LogFolder: "./tests/",
LogMode: "stdout",
APIMode: true,
NbParsers: 1,
Prometheus: true,
HTTPListen: "127.0.0.1:6060",
AcquisitionFile: "tests/acquis.yaml",
CsCliFolder: "./tests/cscli/",
SimulationCfg: &SimulationConfig{
Simulation: false,
Exclusions: nil,
},
SimulationCfgPath: "./tests/simulation.yaml",
OutputConfig: &outputs.OutputFactory{
BackendFolder: "./tests/plugins/backend",
MaxRecords: "",
MaxRecordsAge: "720h",
Flush: false,
Debug: false,
},
},
Args: []string{
"crowdsec",
"-c",
"./tests/config.yaml",
},
err: "",
},
{
name: "load configuration: with -file",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
SingleFile: "./tests/test.file",
SingleFileLabel: "test",
Daemonize: true,
Profiling: true,
WorkingFolder: "./tests/",
DataFolder: "./tests/",
ConfigFolder: "./tests/",
PIDFolder: "./tests/",
LogFolder: "./tests/",
LogMode: "stdout",
APIMode: true,
NbParsers: 1,
Prometheus: true,
HTTPListen: "127.0.0.1:6060",
AcquisitionFile: "tests/acquis.yaml",
CsCliFolder: "./tests/cscli/",
SimulationCfg: &SimulationConfig{
Simulation: false,
Exclusions: nil,
},
SimulationCfgPath: "./tests/simulation.yaml",
OutputConfig: &outputs.OutputFactory{
BackendFolder: "./tests/plugins/backend",
MaxRecords: "",
MaxRecordsAge: "720h",
Flush: false,
Debug: false,
},
},
Args: []string{
"crowdsec",
"-c",
"./tests/config.yaml",
"-file",
"./tests/test.file",
"-type",
"test",
},
err: "",
},
{
name: "load configuration: with -file without -type",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: false,
Profiling: false,
WorkingFolder: "/tmp/",
DataFolder: "/var/lib/crowdsec/data/",
ConfigFolder: "/etc/crowdsec/config/",
PIDFolder: "/var/run/",
LogFolder: "/var/log/",
LogMode: "stdout",
APIMode: false,
NbParsers: 1,
Prometheus: false,
HTTPListen: "127.0.0.1:6060",
},
Args: []string{
"crowdsec",
"-c",
"./tests/config.yaml",
"-file",
"./tests/test.file",
},
err: "-file requires -type",
},
{
name: "load configuration: all flags set",
expectedResult: &CrowdSec{
LogLevel: log.TraceLevel,
Daemonize: true,
Profiling: true,
WorkingFolder: "./tests/",
DataFolder: "./tests/",
ConfigFolder: "./tests/",
PIDFolder: "./tests/",
LogFolder: "./tests/",
LogMode: "stdout",
APIMode: true,
Linter: true,
NbParsers: 1,
Prometheus: true,
HTTPListen: "127.0.0.1:6060",
AcquisitionFile: "./tests/acquis.yaml",
CsCliFolder: "./tests/cscli/",
SimulationCfg: &SimulationConfig{
Simulation: false,
Exclusions: nil,
},
SimulationCfgPath: "./tests/simulation.yaml",
OutputConfig: &outputs.OutputFactory{
BackendFolder: "./tests/plugins/backend",
MaxRecords: "",
MaxRecordsAge: "720h",
Flush: false,
Debug: false,
},
RestoreMode: "./tests/states.json",
DumpBuckets: true,
},
Args: []string{
"crowdsec",
"-c",
"./tests/config.yaml",
"-acquis",
"./tests/acquis.yaml",
"-dump-state",
"-prometheus-metrics",
"-t",
"-daemon",
"-profile",
"-debug",
"-trace",
"-info",
"-restore-state",
"./tests/states.json",
"-api",
},
err: "",
},
{
name: "load configuration: bad config file",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: true,
Profiling: true,
WorkingFolder: "./tests/",
DataFolder: "./tests/",
ConfigFolder: "./tests/",
PIDFolder: "./tests/",
LogFolder: "./tests/",
LogMode: "stdout",
APIMode: true,
Linter: false,
NbParsers: 1,
Prometheus: true,
HTTPListen: "127.0.0.1:6060",
CsCliFolder: "./tests/cscli/",
SimulationCfgPath: "./tests/simulation.yaml",
OutputConfig: &outputs.OutputFactory{
BackendFolder: "./tests/plugins/backend",
MaxRecords: "",
MaxRecordsAge: "720h",
Flush: false,
Debug: false,
},
},
Args: []string{
"crowdsec",
"-c",
"./tests/bad_config.yaml",
},
err: "Error while loading configuration : parse './tests/bad_config.yaml' : yaml: unmarshal errors:\n line 1: field non_existing_field not found in type csconfig.CrowdSec",
},
{
name: "load configuration: bad simulation file",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: true,
Profiling: true,
WorkingFolder: "./tests/",
DataFolder: "./tests/",
ConfigFolder: "./tests/",
PIDFolder: "./tests/",
LogFolder: "./tests/",
LogMode: "stdout",
APIMode: true,
Linter: false,
NbParsers: 1,
Prometheus: true,
AcquisitionFile: "tests/acquis.yaml",
HTTPListen: "127.0.0.1:6060",
CsCliFolder: "./tests/cscli/",
SimulationCfgPath: "./tests/bad_simulation.yaml",
OutputConfig: &outputs.OutputFactory{
BackendFolder: "./tests/plugins/backend",
MaxRecords: "",
MaxRecordsAge: "720h",
Flush: false,
Debug: false,
},
},
Args: []string{
"crowdsec",
"-c",
"./tests/bad_config_simulation.yaml",
},
err: `Error while loading configuration : loading simulation config : while parsing './tests/bad_simulation.yaml' : yaml: unmarshal errors:
line 1: field test not found in type csconfig.SimulationConfig`,
},
{
name: "load configuration: bad config file",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: true,
Profiling: true,
WorkingFolder: "./tests/",
DataFolder: "./tests/",
ConfigFolder: "./tests/",
PIDFolder: "./tests/",
LogFolder: "./tests/",
LogMode: "stdout",
APIMode: true,
Linter: false,
NbParsers: 1,
Prometheus: true,
HTTPListen: "127.0.0.1:6060",
CsCliFolder: "./tests/cscli/",
SimulationCfgPath: "./tests/simulation.yaml",
OutputConfig: &outputs.OutputFactory{
BackendFolder: "./tests/plugins/backend",
MaxRecords: "",
MaxRecordsAge: "720h",
Flush: false,
Debug: false,
},
},
Args: []string{
"crowdsec",
"-c",
"./tests/bad_config.yaml",
},
err: "Error while loading configuration : parse './tests/bad_config.yaml' : yaml: unmarshal errors:\n line 1: field non_existing_field not found in type csconfig.CrowdSec",
},
{
name: "load configuration: non exist simulation file",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: true,
Profiling: true,
WorkingFolder: "./tests/",
DataFolder: "./tests/",
ConfigFolder: "./tests/",
PIDFolder: "./tests/",
LogFolder: "./tests/",
LogMode: "stdout",
APIMode: true,
Linter: false,
NbParsers: 1,
Prometheus: true,
AcquisitionFile: "tests/acquis.yaml",
HTTPListen: "127.0.0.1:6060",
CsCliFolder: "./tests/cscli/",
SimulationCfgPath: "./tests/non_exist.yaml",
OutputConfig: &outputs.OutputFactory{
BackendFolder: "./tests/plugins/backend",
MaxRecords: "",
MaxRecordsAge: "720h",
Flush: false,
Debug: false,
},
},
Args: []string{
"crowdsec",
"-c",
"./tests/bad_config_simulation_1.yaml",
},
err: "Error while loading configuration : loading simulation config : while reading './tests/non_exist.yaml' : open ./tests/non_exist.yaml: no such file or directory",
},
{
name: "load configuration: non existent configuration file",
expectedResult: &CrowdSec{
LogLevel: log.InfoLevel,
Daemonize: false,
Profiling: false,
WorkingFolder: "/tmp/",
DataFolder: "/var/lib/crowdsec/data/",
ConfigFolder: "/etc/crowdsec/config/",
PIDFolder: "/var/run/",
LogFolder: "/var/log/",
LogMode: "stdout",
APIMode: false,
NbParsers: 1,
Prometheus: false,
HTTPListen: "127.0.0.1:6060",
},
Args: []string{
"crowdsec",
"-c",
"./tests/non_exist.yaml",
},
err: "Error while loading configuration : read './tests/non_exist.yaml' : open ./tests/non_exist.yaml: no such file or directory",
},
}
oldArgs := os.Args
defer func() { os.Args = oldArgs }()
for _, test := range tests {
log.Printf("testing '%s'", test.name)
flag.CommandLine = flag.NewFlagSet(test.Args[0], flag.ExitOnError)
result := NewCrowdSecConfig()
os.Args = test.Args
err := result.LoadConfig()
if test.err != "" {
if err == nil {
t.Fatalf("test '%s' should returned an error", test.name)
}
isOk := assert.EqualErrorf(t, err, test.err, "")
if !isOk {
t.Fatalf("test '%s' failed", test.name)
}
}
if test.err == "" && err != nil {
t.Fatalf("test '%s' return an error : %s", test.name, err)
}
isOk := assert.Equal(t, test.expectedResult, result)
if !isOk {
t.Fatalf("test '%s' failed", test.name)
}
log.Infof("test '%s' : OK", test.name)
}
}