diff --git a/action.yml b/action.yml index 5c4599f..78635a0 100644 --- a/action.yml +++ b/action.yml @@ -68,6 +68,7 @@ runs: ${{ inputs.sudo }} mkdir -p /usr/share/falco/plugins ${{ inputs.sudo }} falcoctl artifact install k8saudit-rules ${{ inputs.sudo }} falcoctl artifact install cloudtrail-rules + ${{ inputs.sudo }} falcoctl artifact install dummy - name: Install dependencies for falco-driver-loader tests if: ${{ inputs.test-drivers == 'true' }} diff --git a/pkg/falco/tester_options.go b/pkg/falco/tester_options.go index d5836f8..ff92f84 100644 --- a/pkg/falco/tester_options.go +++ b/pkg/falco/tester_options.go @@ -84,6 +84,17 @@ func WithDisabledSources(sources ...string) TestOption { return withMultipleArgValues("--disable-source", sources...) } +// WithPrometheusMetrics runs Falco enabling prometheus metrics endpoint. +func WithPrometheusMetrics() TestOption { + return func(o *testOptions) { + o.args = append(o.args, "-o", "metrics.enabled=true") + o.args = append(o.args, "-o", "metrics.output_rule=true") + o.args = append(o.args, "-o", "metrics.interval=2s") + o.args = append(o.args, "-o", "webserver.enabled=true") + o.args = append(o.args, "-o", "webserver.prometheus_metrics_enabled=true") + } +} + // WithMinRulePriority runs Falco by forcing a mimimum rules priority. func WithMinRulePriority(priority string) TestOption { return func(o *testOptions) { diff --git a/tests/data/plugins/plugins.go b/tests/data/plugins/plugins.go index aba58b6..8a9c4ea 100644 --- a/tests/data/plugins/plugins.go +++ b/tests/data/plugins/plugins.go @@ -31,3 +31,7 @@ var CloudtrailPlugin = run.NewLocalFileAccessor( var JSONPlugin = run.NewLocalFileAccessor( "libjson.so", "/usr/share/falco/plugins/libjson.so") + +var DummyPlugin = run.NewLocalFileAccessor( + "libdummy.so", + "/usr/share/falco/plugins/libdummy.so") diff --git a/tests/dummy/dummy_test.go b/tests/dummy/dummy_test.go new file mode 100644 index 0000000..1f9650d --- /dev/null +++ b/tests/dummy/dummy_test.go @@ -0,0 +1,62 @@ +package testdummy + +import ( + "github.com/falcosecurity/testing/pkg/falco" + "github.com/falcosecurity/testing/pkg/run" + "github.com/falcosecurity/testing/tests" + "github.com/falcosecurity/testing/tests/data/plugins" + "github.com/falcosecurity/testing/tests/data/rules" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "net/http" + "sync" + "testing" + "time" +) + +func runFalcoWithDummy(t *testing.T, r run.Runner, opts ...falco.TestOption) *falco.TestOutput { + config, err := falco.NewPluginConfig( + "plugin-config.yaml", + &falco.PluginConfigInfo{ + Name: "dummy", + Library: plugins.DummyPlugin.Name(), + OpenParams: `'{"start": 1, "maxEvents": 2000000000}'`, + }, + ) + require.Nil(t, err) + options := []falco.TestOption{ + falco.WithEnabledSources("dummy"), + falco.WithConfig(config), + falco.WithExtraFiles(plugins.DummyPlugin), + } + options = append(options, opts...) + return falco.Test(r, options...) +} + +func TestDummy_PrometheusMetrics(t *testing.T) { + var ( + wg sync.WaitGroup + metricsErr error + ) + wg.Add(1) + + go func() { + defer wg.Done() + time.Sleep(2 * time.Second) + _, metricsErr = http.Get("http://127.0.0.1:8765/metrics") + }() + + falcoRes := runFalcoWithDummy(t, + tests.NewFalcoExecutableRunner(t), + falco.WithPrometheusMetrics(), + falco.WithRules(rules.SingleRule), + falco.WithStopAfter(5*time.Second), + falco.WithArgs("-o", "engine.kind=nodriver"), + ) + assert.NoError(t, falcoRes.Err(), "%s", falcoRes.Stderr()) + assert.Equal(t, 0, falcoRes.ExitCode()) + + wg.Wait() + + assert.NoError(t, metricsErr) +} diff --git a/tests/dummy/generate.go b/tests/dummy/generate.go new file mode 100644 index 0000000..f77b745 --- /dev/null +++ b/tests/dummy/generate.go @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2023 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +package testdummy + +//go:generate go test ./... -c -o ../../build/dummy.test diff --git a/tests/falco/miscs_test.go b/tests/falco/miscs_test.go index 2feb954..5b2bd5e 100644 --- a/tests/falco/miscs_test.go +++ b/tests/falco/miscs_test.go @@ -21,8 +21,10 @@ package testfalco import ( "github.com/falcosecurity/testing/pkg/run" "github.com/falcosecurity/testing/tests/data/rules" + "net/http" "os" "path/filepath" + "sync" "testing" "time" @@ -106,3 +108,31 @@ func TestFalco_Miscs_HotReload(t *testing.T) { // We want to be sure that the hot reload was triggered assert.Regexp(t, `SIGHUP received, restarting...`, falcoRes.Stderr()) } + +func TestFalco_Miscs_PrometheusMetricsNoDriver(t *testing.T) { + var ( + wg sync.WaitGroup + metricsErr error + ) + wg.Add(1) + + go func() { + defer wg.Done() + time.Sleep(2 * time.Second) + _, metricsErr = http.Get("http://127.0.0.1:8765/metrics") + }() + + falcoRes := falco.Test( + tests.NewFalcoExecutableRunner(t), + falco.WithPrometheusMetrics(), + falco.WithRules(rules.SingleRule), + falco.WithStopAfter(5*time.Second), + falco.WithArgs("-o", "engine.kind=nodriver"), + ) + assert.NoError(t, falcoRes.Err(), "%s", falcoRes.Stderr()) + assert.Equal(t, 0, falcoRes.ExitCode()) + + wg.Wait() + + assert.NoError(t, metricsErr) +}