123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023 |
- package setup_test
- import (
- "fmt"
- "os"
- "os/exec"
- "runtime"
- "testing"
- "github.com/lithammer/dedent"
- "github.com/stretchr/testify/require"
- "github.com/crowdsecurity/go-cs-lib/cstest"
- "github.com/crowdsecurity/crowdsec/pkg/setup"
- )
- //nolint:dupword
- var fakeSystemctlOutput = `UNIT FILE STATE VENDOR PRESET
- crowdsec-setup-detect.service enabled enabled
- apache2.service enabled enabled
- apparmor.service enabled enabled
- apport.service enabled enabled
- atop.service enabled enabled
- atopacct.service enabled enabled
- finalrd.service enabled enabled
- fwupd-refresh.service enabled enabled
- fwupd.service enabled enabled
- 9 unit files listed.`
- func fakeExecCommandNotFound(command string, args ...string) *exec.Cmd {
- cs := []string{"-test.run=TestSetupHelperProcess", "--", command}
- cs = append(cs, args...)
- cmd := exec.Command("this-command-does-not-exist", cs...)
- cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
- return cmd
- }
- func fakeExecCommand(command string, args ...string) *exec.Cmd {
- cs := []string{"-test.run=TestSetupHelperProcess", "--", command}
- cs = append(cs, args...)
- //nolint:gosec
- cmd := exec.Command(os.Args[0], cs...)
- cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
- return cmd
- }
- func TestSetupHelperProcess(t *testing.T) {
- if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
- return
- }
- fmt.Fprint(os.Stdout, fakeSystemctlOutput)
- os.Exit(0)
- }
- func tempYAML(t *testing.T, content string) os.File {
- t.Helper()
- require := require.New(t)
- file, err := os.CreateTemp("", "")
- require.NoError(err)
- _, err = file.WriteString(dedent.Dedent(content))
- require.NoError(err)
- err = file.Close()
- require.NoError(err)
- file, err = os.Open(file.Name())
- require.NoError(err)
- return *file
- }
- func TestPathExists(t *testing.T) {
- t.Parallel()
- type test struct {
- path string
- expected bool
- }
- tests := []test{
- {"/this-should-not-exist", false},
- }
- if runtime.GOOS == "windows" {
- tests = append(tests, test{`C:\`, true})
- } else {
- tests = append(tests, test{"/tmp", true})
- }
- for _, tc := range tests {
- tc := tc
- env := setup.NewExprEnvironment(setup.DetectOptions{}, setup.ExprOS{})
- t.Run(tc.path, func(t *testing.T) {
- t.Parallel()
- actual := env.PathExists(tc.path)
- require.Equal(t, tc.expected, actual)
- })
- }
- }
- func TestVersionCheck(t *testing.T) {
- t.Parallel()
- tests := []struct {
- version string
- constraint string
- expected bool
- expectedErr string
- }{
- {"1", "=1", true, ""},
- {"1", "!=1", false, ""},
- {"1", "<=1", true, ""},
- {"1", ">1", false, ""},
- {"1", ">=1", true, ""},
- {"1.0", "<1.0", false, ""},
- {"1", "<1", false, ""},
- {"1.3.5", "1.3", true, ""},
- {"1.0", "<1.0", false, ""},
- {"1.0", "<=1.0", true, ""},
- {"2", ">1, <3", true, ""},
- {"2", "<=2, >=2.2", false, ""},
- {"2.3", "~2", true, ""},
- {"2.3", "=2", true, ""},
- {"1.1.1", "=1.1", true, ""},
- {"1.1.1", "1.1", true, ""},
- {"1.1", "!=1.1.1", true, ""},
- {"1.1", "~1.1.1", false, ""},
- {"1.1.1", "~1.1", true, ""},
- {"1.1.3", "~1.1", true, ""},
- {"19.04", "<19.10", true, ""},
- {"19.04", ">=19.10", false, ""},
- {"19.04", "=19.4", true, ""},
- {"19.04", "~19.4", true, ""},
- {"1.2.3", "~1.2", true, ""},
- {"1.2.3", "!=1.2", false, ""},
- {"1.2.3", "1.1.1 - 1.3.4", true, ""},
- {"1.3.5", "1.1.1 - 1.3.4", false, ""},
- {"1.3.5", "=1", true, ""},
- {"1.3.5", "1", true, ""},
- }
- for _, tc := range tests {
- tc := tc
- e := setup.ExprOS{RawVersion: tc.version}
- t.Run(fmt.Sprintf("Check(%s,%s)", tc.version, tc.constraint), func(t *testing.T) {
- t.Parallel()
- actual, err := e.VersionCheck(tc.constraint)
- cstest.RequireErrorContains(t, err, tc.expectedErr)
- require.Equal(t, tc.expected, actual)
- })
- }
- }
- // This is not required for Masterminds/semver
- /*
- func TestNormalizeVersion(t *testing.T) {
- t.Parallel()
- tests := []struct {
- version string
- expected string
- }{
- {"0", "0"},
- {"2", "2"},
- {"3.14", "3.14"},
- {"1.0", "1.0"},
- {"18.04", "18.4"},
- {"0.0.0", "0.0.0"},
- {"18.04.0", "18.4.0"},
- {"18.0004.0", "18.4.0"},
- {"21.04.2", "21.4.2"},
- {"050", "50"},
- {"trololo", "trololo"},
- {"0001.002.03", "1.2.3"},
- {"0001.002.03-trololo", "0001.002.03-trololo"},
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.version, func(t *testing.T) {
- t.Parallel()
- actual := setup.NormalizeVersion(tc.version)
- require.Equal(t, tc.expected, actual)
- })
- }
- }
- */
- func TestListSupported(t *testing.T) {
- t.Parallel()
- tests := []struct {
- name string
- yml string
- expected []string
- expectedErr string
- }{
- {
- "list configured services",
- `
- version: 1.0
- detect:
- foo:
- bar:
- baz:
- `,
- []string{"foo", "bar", "baz"},
- "",
- },
- {
- "invalid yaml: blahblah",
- "blahblah",
- nil,
- "yaml: unmarshal errors:",
- },
- {
- "invalid yaml: tabs are not allowed",
- `
- version: 1.0
- detect:
- foos:
- `,
- nil,
- "yaml: line 4: found character that cannot start any token",
- },
- {
- "invalid yaml: no version",
- "{}",
- nil,
- "missing version tag (must be 1.0)",
- },
- {
- "invalid yaml: bad version",
- "version: 2.0",
- nil,
- "invalid version tag '2.0' (must be 1.0)",
- },
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- f := tempYAML(t, tc.yml)
- defer os.Remove(f.Name())
- supported, err := setup.ListSupported(&f)
- cstest.RequireErrorContains(t, err, tc.expectedErr)
- require.ElementsMatch(t, tc.expected, supported)
- })
- }
- }
- func TestApplyRules(t *testing.T) {
- t.Parallel()
- require := require.New(t)
- tests := []struct {
- name string
- rules []string
- expectedOk bool
- expectedErr string
- }{
- {
- "empty list is always true", // XXX or false?
- []string{},
- true,
- "",
- },
- {
- "simple true expression",
- []string{"1+1==2"},
- true,
- "",
- },
- {
- "simple false expression",
- []string{"2+2==5"},
- false,
- "",
- },
- {
- "all expressions are true",
- []string{"1+2==3", "1!=2"},
- true,
- "",
- },
- {
- "all expressions must be true",
- []string{"true", "1==3", "1!=2"},
- false,
- "",
- },
- {
- "each expression must be a boolan",
- []string{"true", "\"notabool\""},
- false,
- "rule '\"notabool\"': type must be a boolean",
- },
- {
- // we keep evaluating expressions to ensure that the
- // file is formally correct, even if it can some time.
- "each expression must be a boolan (no short circuit)",
- []string{"false", "3"},
- false,
- "rule '3': type must be a boolean",
- },
- {
- "unknown variable",
- []string{"false", "doesnotexist"},
- false,
- "rule 'doesnotexist': cannot fetch doesnotexist from",
- },
- {
- "unknown expression",
- []string{"false", "doesnotexist()"},
- false,
- "rule 'doesnotexist()': cannot fetch doesnotexist from",
- },
- }
- env := setup.ExprEnvironment{}
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- t.Parallel()
- svc := setup.Service{When: tc.rules}
- _, actualOk, err := setup.ApplyRules(svc, env) //nolint:typecheck,nolintlint // exported only for tests
- cstest.RequireErrorContains(t, err, tc.expectedErr)
- require.Equal(tc.expectedOk, actualOk)
- })
- }
- }
- // XXX TODO: TestApplyRules with journalctl default
- func TestUnitFound(t *testing.T) {
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- defer func() { setup.ExecCommand = exec.Command }()
- env := setup.NewExprEnvironment(setup.DetectOptions{}, setup.ExprOS{})
- installed, err := env.UnitFound("crowdsec-setup-detect.service")
- require.NoError(err)
- require.Equal(true, installed)
- }
- // TODO apply rules to filter a list of Service structs
- // func testFilterWithRules(t *testing.T) {
- // }
- func TestDetectSimpleRule(t *testing.T) {
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- f := tempYAML(t, `
- version: 1.0
- detect:
- good:
- when:
- - true
- bad:
- when:
- - false
- ugly:
- `)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{})
- require.NoError(err)
- expected := []setup.ServiceSetup{
- {DetectedService: "good"},
- {DetectedService: "ugly"},
- }
- require.ElementsMatch(expected, detected.Setup)
- }
- func TestDetectUnitError(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("skipping on windows")
- }
- require := require.New(t)
- setup.ExecCommand = fakeExecCommandNotFound
- defer func() { setup.ExecCommand = exec.Command }()
- tests := []struct {
- name string
- config string
- expected setup.Setup
- expectedErr string
- }{
- {
- "error is reported if systemctl does not exist",
- `
- version: 1.0
- detect:
- wizard:
- when:
- - UnitFound("crowdsec-setup-detect.service")`,
- setup.Setup{[]setup.ServiceSetup{}},
- `while looking for service wizard: rule 'UnitFound("crowdsec-setup-detect.service")': ` +
- `running systemctl: exec: "this-command-does-not-exist": executable file not found in $PATH`,
- },
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- f := tempYAML(t, tc.config)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{})
- cstest.RequireErrorContains(t, err, tc.expectedErr)
- require.Equal(tc.expected, detected)
- })
- }
- }
- func TestDetectUnit(t *testing.T) {
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- defer func() { setup.ExecCommand = exec.Command }()
- tests := []struct {
- name string
- config string
- expected setup.Setup
- expectedErr string
- }{
- // {
- // "detect a single unit, with default log filter",
- // `
- // version: 1.0
- // detect:
- // wizard:
- // when:
- // - UnitFound("crowdsec-setup-detect.service")
- // datasource:
- // labels:
- // type: syslog
- // sorcerer:
- // when:
- // - UnitFound("sorcerer.service")`,
- // setup.Setup{
- // Setup: []setup.ServiceSetup{
- // {
- // DetectedService: "wizard",
- // DataSource: setup.DataSourceItem{
- // "Labels": map[string]string{"type": "syslog"},
- // "JournalCTLFilter": []string{"_SYSTEMD_UNIT=crowdsec-setup-detect.service"},
- // },
- // },
- // },
- // },
- // "",
- // },
- // {
- // "detect a single unit, but type label is missing",
- // `
- // version: 1.0
- // detect:
- // wizard:
- // when:
- // - UnitFound("crowdsec-setup-detect.service")`,
- // setup.Setup{},
- // "missing type label for service wizard",
- // },
- {
- "detect unit and pick up acquisistion filter",
- `
- version: 1.0
- detect:
- wizard:
- when:
- - UnitFound("crowdsec-setup-detect.service")
- datasource:
- source: journalctl
- labels:
- type: syslog
- journalctl_filter:
- - _MY_CUSTOM_FILTER=something`,
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {
- DetectedService: "wizard",
- DataSource: setup.DataSourceItem{
- // XXX this should not be DataSourceItem ??
- "source": "journalctl",
- "labels": setup.DataSourceItem{"type": "syslog"},
- "journalctl_filter": []interface{}{"_MY_CUSTOM_FILTER=something"},
- },
- },
- },
- },
- "",
- },
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- f := tempYAML(t, tc.config)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{})
- cstest.RequireErrorContains(t, err, tc.expectedErr)
- require.Equal(tc.expected, detected)
- })
- }
- }
- func TestDetectForcedUnit(t *testing.T) {
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- defer func() { setup.ExecCommand = exec.Command }()
- f := tempYAML(t, `
- version: 1.0
- detect:
- wizard:
- when:
- - UnitFound("crowdsec-setup-forced.service")
- datasource:
- source: journalctl
- labels:
- type: syslog
- journalctl_filter:
- - _SYSTEMD_UNIT=crowdsec-setup-forced.service
- `)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{ForcedUnits: []string{"crowdsec-setup-forced.service"}})
- require.NoError(err)
- expected := setup.Setup{
- Setup: []setup.ServiceSetup{
- {
- DetectedService: "wizard",
- DataSource: setup.DataSourceItem{
- "source": "journalctl",
- "labels": setup.DataSourceItem{"type": "syslog"},
- "journalctl_filter": []interface{}{"_SYSTEMD_UNIT=crowdsec-setup-forced.service"},
- },
- },
- },
- }
- require.Equal(expected, detected)
- }
- func TestDetectForcedProcess(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("skipping on windows")
- // while looking for service wizard: rule 'ProcessRunning("foobar")': while looking up running processes: could not get Name: A device attached to the system is not functioning.
- }
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- defer func() { setup.ExecCommand = exec.Command }()
- f := tempYAML(t, `
- version: 1.0
- detect:
- wizard:
- when:
- - ProcessRunning("foobar")
- `)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{ForcedProcesses: []string{"foobar"}})
- require.NoError(err)
- expected := setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "wizard"},
- },
- }
- require.Equal(expected, detected)
- }
- func TestDetectSkipService(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skip("skipping on windows")
- }
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- defer func() { setup.ExecCommand = exec.Command }()
- f := tempYAML(t, `
- version: 1.0
- detect:
- wizard:
- when:
- - ProcessRunning("foobar")
- `)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{ForcedProcesses: []string{"foobar"}, SkipServices: []string{"wizard"}})
- require.NoError(err)
- expected := setup.Setup{[]setup.ServiceSetup{}}
- require.Equal(expected, detected)
- }
- func TestDetectForcedOS(t *testing.T) {
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- defer func() { setup.ExecCommand = exec.Command }()
- type test struct {
- name string
- config string
- forced setup.ExprOS
- expected setup.Setup
- expectedErr string
- }
- tests := []test{
- {
- "detect OS - force linux",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.Family == "linux"`,
- setup.ExprOS{Family: "linux"},
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "linux"},
- },
- },
- "",
- },
- {
- "detect OS - force windows",
- `
- version: 1.0
- detect:
- windows:
- when:
- - OS.Family == "windows"`,
- setup.ExprOS{Family: "windows"},
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "windows"},
- },
- },
- "",
- },
- {
- "detect OS - ubuntu (no match)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.Family == "linux" && OS.ID == "ubuntu"`,
- setup.ExprOS{Family: "linux"},
- setup.Setup{[]setup.ServiceSetup{}},
- "",
- },
- {
- "detect OS - ubuntu (match)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.Family == "linux" && OS.ID == "ubuntu"`,
- setup.ExprOS{Family: "linux", ID: "ubuntu"},
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "linux"},
- },
- },
- "",
- },
- {
- "detect OS - ubuntu (match with version)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.Family == "linux" && OS.ID == "ubuntu" && OS.VersionCheck("19.04")`,
- setup.ExprOS{Family: "linux", ID: "ubuntu", RawVersion: "19.04"},
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "linux"},
- },
- },
- "",
- },
- {
- "detect OS - ubuntu >= 20.04 (no match: no version detected)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu" && OS.VersionCheck(">=20.04")`,
- setup.ExprOS{Family: "linux"},
- setup.Setup{[]setup.ServiceSetup{}},
- "",
- },
- {
- "detect OS - ubuntu >= 20.04 (no match: version is lower)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu" && OS.VersionCheck(">=20.04")`,
- setup.ExprOS{Family: "linux", ID: "ubuntu", RawVersion: "19.10"},
- setup.Setup{[]setup.ServiceSetup{}},
- "",
- },
- {
- "detect OS - ubuntu >= 20.04 (match: same version)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu" && OS.VersionCheck(">=20.04")`,
- setup.ExprOS{Family: "linux", ID: "ubuntu", RawVersion: "20.04"},
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "linux"},
- },
- },
- "",
- },
- {
- "detect OS - ubuntu >= 20.04 (match: version is higher)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu" && OS.VersionCheck(">=20.04")`,
- setup.ExprOS{Family: "linux", ID: "ubuntu", RawVersion: "22.04"},
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "linux"},
- },
- },
- "",
- },
- {
- "detect OS - ubuntu < 20.04 (no match: no version detected)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu" && OS.VersionCheck("<20.04")`,
- setup.ExprOS{Family: "linux"},
- setup.Setup{[]setup.ServiceSetup{}},
- "",
- },
- {
- "detect OS - ubuntu < 20.04 (no match: version is higher)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu" && OS.VersionCheck("<20.04")`,
- setup.ExprOS{Family: "linux", ID: "ubuntu", RawVersion: "20.10"},
- setup.Setup{[]setup.ServiceSetup{}},
- "",
- },
- {
- "detect OS - ubuntu < 20.04 (no match: same version)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu" && OS.VersionCheck("<20.04")`,
- setup.ExprOS{Family: "linux", ID: "ubuntu", RawVersion: "20.04"},
- setup.Setup{[]setup.ServiceSetup{}},
- "",
- },
- {
- "detect OS - ubuntu < 20.04 (match: version is lower)",
- `
- version: 1.0
- detect:
- linux:
- when:
- - OS.ID == "ubuntu"
- - OS.VersionCheck("<20.04")`,
- setup.ExprOS{Family: "linux", ID: "ubuntu", RawVersion: "19.10"},
- setup.Setup{
- Setup: []setup.ServiceSetup{
- {DetectedService: "linux"},
- },
- },
- "",
- },
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- f := tempYAML(t, tc.config)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{ForcedOS: tc.forced})
- cstest.RequireErrorContains(t, err, tc.expectedErr)
- require.Equal(tc.expected, detected)
- })
- }
- }
- func TestDetectDatasourceValidation(t *testing.T) {
- // It could be a good idea to test UnmarshalConfig() separately in addition
- // to Configure(), in each datasource. For now, we test these here.
- require := require.New(t)
- setup.ExecCommand = fakeExecCommand
- defer func() { setup.ExecCommand = exec.Command }()
- type test struct {
- name string
- config string
- expected setup.Setup
- expectedErr string
- }
- tests := []test{
- {
- name: "source is empty",
- config: `
- version: 1.0
- detect:
- wizard:
- datasource:
- labels:
- type: something`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for wizard: source is empty",
- }, {
- name: "source is unknown",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: wombat`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: unknown source 'wombat'",
- }, {
- name: "source is misplaced",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: file`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "yaml: unmarshal errors:\n line 6: field source not found in type setup.Service",
- }, {
- name: "source is mismatched",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: journalctl
- filename: /path/to/file.log`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: cannot parse JournalCtlSource configuration: yaml: unmarshal errors:\n line 1: field filename not found in type journalctlacquisition.JournalCtlConfiguration",
- }, {
- name: "source file: required fields",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: file`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: no filename or filenames configuration provided",
- }, {
- name: "source journalctl: required fields",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: journalctl`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: journalctl_filter is required",
- }, {
- name: "source cloudwatch: required fields",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: cloudwatch`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: group_name is mandatory for CloudwatchSource",
- }, {
- name: "source syslog: all fields are optional",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: syslog`,
- expected: setup.Setup{
- Setup: []setup.ServiceSetup{
- {
- DetectedService: "foobar",
- DataSource: setup.DataSourceItem{"source": "syslog"},
- },
- },
- },
- }, {
- name: "source docker: required fields",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: docker`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: no containers names or containers ID configuration provided",
- }, {
- name: "source kinesis: required fields (enhanced fanout=false)",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: kinesis`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: stream_name is mandatory when use_enhanced_fanout is false",
- }, {
- name: "source kinesis: required fields (enhanced fanout=true)",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: kinesis
- use_enhanced_fanout: true`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: stream_arn is mandatory when use_enhanced_fanout is true",
- }, {
- name: "source kafka: required fields",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: kafka`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: cannot create a kafka reader with an empty list of broker addresses",
- }, {
- name: "source loki: required fields",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: loki`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: Loki query is mandatory",
- },
- }
- if runtime.GOOS == "windows" {
- tests = append(tests, test{
- name: "source wineventlog: required fields",
- config: `
- version: 1.0
- detect:
- foobar:
- datasource:
- source: wineventlog`,
- expected: setup.Setup{Setup: []setup.ServiceSetup{}},
- expectedErr: "invalid datasource for foobar: event_channel or xpath_query must be set",
- })
- }
- for _, tc := range tests {
- tc := tc
- t.Run(tc.name, func(t *testing.T) {
- f := tempYAML(t, tc.config)
- defer os.Remove(f.Name())
- detected, err := setup.Detect(&f, setup.DetectOptions{})
- cstest.RequireErrorContains(t, err, tc.expectedErr)
- require.Equal(tc.expected, detected)
- })
- }
- }
|