From af8c55330dad73b1e56da52fdc274583e73db64b Mon Sep 17 00:00:00 2001 From: mmetc <92726601+mmetc@users.noreply.github.com> Date: Fri, 18 Mar 2022 10:13:12 +0100 Subject: [PATCH] [wip] bats changes for modular fixtures (#1371) * target: tests/.environment.sh * don't pass BIN_DIR around * manage db backup/restore separately * don't export CONFIG_DIR, DATA_DIR (derive path locations from CONFIG_YAML); redirect stdout, stderr to &3 by default in setup_file, teardown_file --- tests/bats.mk | 36 ++++++------ tests/bats/01_base.bats | 7 ++- tests/bats/02_nolapi.bats | 16 +++--- tests/bats/03_noagent.bats | 6 +- tests/bats/04_nocapi.bats | 6 +- tests/bats/10_bouncers.bats | 4 +- tests/bats/20_collections.bats | 4 +- tests/bats/30_machines.bats | 4 +- tests/bats/40_cold-logs.bats | 6 +- tests/bats/40_live-ban.bats | 7 ++- tests/bats/50_simulation.bats | 4 +- tests/bats/70_http_plugin.bats | 11 ++-- tests/bats/71_dummy_plugin.bats | 17 +++--- tests/bats/80_alerts.bats | 4 +- tests/bats/90_decisions.bats | 4 +- tests/bats/97_ipv4_single.bats | 4 +- tests/bats/97_ipv6_single.bats | 4 +- tests/bats/98_ipv4_range.bats | 4 +- tests/bats/98_ipv6_range.bats | 4 +- tests/bats/99_lapi-stream-mode-scopes.bats | 4 +- tests/bats/99_lapi-stream-mode.bats | 6 +- tests/collect-hub-coverage | 2 +- tests/generate-hub-tests | 5 +- tests/instance-crowdsec | 11 ++-- tests/instance-data | 66 +++++++++++++--------- tests/instance-db | 7 +++ tests/instance-mock-http | 2 +- tests/instance-sqlite | 52 +++++++++++++++++ tests/lib/setup_file.sh | 29 +++++++--- tests/lib/teardown_file.sh | 3 + 30 files changed, 215 insertions(+), 124 deletions(-) create mode 100755 tests/instance-db create mode 100755 tests/instance-sqlite diff --git a/tests/bats.mk b/tests/bats.mk index b2383cdf2..7fd1fb253 100644 --- a/tests/bats.mk +++ b/tests/bats.mk @@ -1,9 +1,14 @@ + +# contains scripts, bats submodules, local instances and functional test suite TEST_DIR = $(CURDIR)/tests + +# contains a local instance of crowdsec, complete with configuration and data LOCAL_DIR = $(TEST_DIR)/local BIN_DIR = $(LOCAL_DIR)/bin CONFIG_DIR = $(LOCAL_DIR)/etc/crowdsec DATA_DIR = $(LOCAL_DIR)/var/lib/crowdsec/data + LOCAL_INIT_DIR = $(TEST_DIR)/local-init LOG_DIR = $(LOCAL_DIR)/var/log PID_DIR = $(LOCAL_DIR)/var/run @@ -12,9 +17,9 @@ PLUGIN_DIR = $(LOCAL_DIR)/lib/crowdsec/plugins define ENV := export TEST_DIR="$(TEST_DIR)" export LOCAL_DIR="$(LOCAL_DIR)" -export BIN_DIR="$(BIN_DIR)" -export CONFIG_DIR="$(CONFIG_DIR)" -export DATA_DIR="$(DATA_DIR)" +export CROWDSEC="$(BIN_DIR)/crowdsec" +export CSCLI="$(BIN_DIR)/cscli" +export CONFIG_YAML="$(CONFIG_DIR)/config.yaml" export LOCAL_INIT_DIR="$(LOCAL_INIT_DIR)" export LOG_DIR="$(LOG_DIR)" export PID_DIR="$(PID_DIR)" @@ -24,32 +29,29 @@ endef bats-all: bats-clean bats-build bats-test # Source this to run the scripts outside of the Makefile -bats-environment: +tests/.environment.sh: $(file >$(TEST_DIR)/.environment.sh,$(ENV)) +bats-environment: tests/.environment.sh + # Verify dependencies and submodules bats-check-requirements: @$(TEST_DIR)/check-requirements -# Builds and installs crowdsec in a local directory +# Build and installs crowdsec in a local directory +# Create a reusable package with initial configuration + data +# Generate dynamic tests bats-build: bats-environment bats-check-requirements @DEFAULT_CONFIGDIR=$(CONFIG_DIR) DEFAULT_DATADIR=$(DATA_DIR) $(MAKE) build - @mkdir -p $(BIN_DIR) $(CONFIG_DIR) $(DATA_DIR) $(LOG_DIR) $(PID_DIR) $(LOCAL_INIT_DIR) $(PLUGIN_DIR) - @install -m 0755 cmd/crowdsec/crowdsec $(BIN_DIR)/ - @install -m 0755 cmd/crowdsec-cli/cscli $(BIN_DIR)/ - @install -m 0755 plugins/notifications/email/notification-email $(PLUGIN_DIR)/ - @install -m 0755 plugins/notifications/http/notification-http $(PLUGIN_DIR)/ - @install -m 0755 plugins/notifications/slack/notification-slack $(PLUGIN_DIR)/ - @install -m 0755 plugins/notifications/splunk/notification-splunk $(PLUGIN_DIR)/ - @install -m 0755 plugins/notifications/dummy/notification-dummy $(PLUGIN_DIR)/ - # Create a reusable package with initial configuration + data + @mkdir -p $(BIN_DIR) $(LOG_DIR) $(PID_DIR) $(PLUGIN_DIR) + @install -m 0755 cmd/crowdsec/crowdsec cmd/crowdsec-cli/cscli $(BIN_DIR)/ + @install -m 0755 plugins/notifications/*/notification-* $(PLUGIN_DIR)/ @$(TEST_DIR)/instance-data make - # Generate dynamic tests @$(TEST_DIR)/generate-hub-tests -# Removes the local crowdsec installation and the fixture config + data +# Remove the local crowdsec installation and the fixture config + data bats-clean: - @$(RM) -r $(LOCAL_DIR) $(LOCAL_INIT_DIR) $(TEST_DIR)/dyn-bats/*.bats + @$(RM) -r $(LOCAL_DIR) $(LOCAL_INIT_DIR) $(TEST_DIR)/dyn-bats/*.bats tests/.environment.sh # Run the test suite bats-test: bats-environment bats-check-requirements diff --git a/tests/bats/01_base.bats b/tests/bats/01_base.bats index 41c4dd580..664480d9c 100644 --- a/tests/bats/01_base.bats +++ b/tests/bats/01_base.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { @@ -133,7 +133,8 @@ declare stderr assert_output --partial "# bash completion for cscli" run -0 cscli completion zsh assert_output --partial "# zsh completion for cscli" - rm "${CONFIG_DIR}/config.yaml" + + rm "${CONFIG_YAML}" run -0 cscli completion bash assert_output --partial "# bash completion for cscli" run -0 cscli completion zsh diff --git a/tests/bats/02_nolapi.bats b/tests/bats/02_nolapi.bats index ac8382086..2a46e5917 100644 --- a/tests/bats/02_nolapi.bats +++ b/tests/bats/02_nolapi.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { @@ -35,7 +35,7 @@ declare stderr } @test "$FILE crowdsec should not run without LAPI (no api.server in configuration file)" { - yq 'del(.api.server)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.api.server)' -i "${CONFIG_YAML}" run -1 --separate-stderr timeout 1s "${CROWDSEC}" run -0 echo "$stderr" @@ -43,7 +43,7 @@ declare stderr } @test "$FILE capi status shouldn't be ok without api.server" { - yq 'del(.api.server)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.api.server)' -i "${CONFIG_YAML}" run -1 --separate-stderr cscli capi status run -0 echo "$stderr" @@ -51,7 +51,7 @@ declare stderr } @test "$FILE cscli config show -o human" { - yq 'del(.api.server)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.api.server)' -i "${CONFIG_YAML}" run -0 cscli config show -o human assert_output --partial "Global:" assert_output --partial "Crowdsec:" @@ -60,7 +60,7 @@ declare stderr } @test "$FILE cscli config backup" { - yq 'del(.api.server)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.api.server)' -i "${CONFIG_YAML}" backupdir=$(TMPDIR="${BATS_TEST_TMPDIR}" mktemp -u) run -0 cscli config backup "${backupdir}" assert_output --partial "Starting configuration backup" @@ -73,7 +73,7 @@ declare stderr } @test "$FILE lapi status shouldn't be ok without api.server" { - yq 'del(.api.server)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.api.server)' -i "${CONFIG_YAML}" ./instance-crowdsec start run -1 --separate-stderr cscli machines list run -0 echo "$stderr" @@ -82,7 +82,7 @@ declare stderr @test "$FILE cscli metrics" { skip 'need to trigger metrics with a live parse' - yq 'del(.api.server)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.api.server)' -i "${CONFIG_YAML}" ./instance-crowdsec start run -0 --separate-stderr cscli metrics assert_output --partial "ROUTE" diff --git a/tests/bats/03_noagent.bats b/tests/bats/03_noagent.bats index 8f7f1dead..e1ff05950 100644 --- a/tests/bats/03_noagent.bats +++ b/tests/bats/03_noagent.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { @@ -25,7 +25,7 @@ declare stderr #---------- config_disable_agent() { - yq 'del(.crowdsec_service)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.crowdsec_service)' -i "${CONFIG_YAML}" } @test "$FILE with agent: test without -no-cs flag" { diff --git a/tests/bats/04_nocapi.bats b/tests/bats/04_nocapi.bats index f3b06f711..38c5297b7 100644 --- a/tests/bats/04_nocapi.bats +++ b/tests/bats/04_nocapi.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { @@ -25,7 +25,7 @@ declare stderr #---------- config_disable_capi() { - yq 'del(.api.server.online_client)' -i "${CONFIG_DIR}/config.yaml" + yq 'del(.api.server.online_client)' -i "${CONFIG_YAML}" } @test "$FILE without capi: crowdsec LAPI should still work" { diff --git a/tests/bats/10_bouncers.bats b/tests/bats/10_bouncers.bats index acb2e13e5..afb533f5c 100644 --- a/tests/bats/10_bouncers.bats +++ b/tests/bats/10_bouncers.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/20_collections.bats b/tests/bats/20_collections.bats index ae45ad425..611b9d87f 100644 --- a/tests/bats/20_collections.bats +++ b/tests/bats/20_collections.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/30_machines.bats b/tests/bats/30_machines.bats index db082ee11..502aaf863 100644 --- a/tests/bats/30_machines.bats +++ b/tests/bats/30_machines.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/40_cold-logs.bats b/tests/bats/40_cold-logs.bats index 713577a6b..dcbf03f4a 100644 --- a/tests/bats/40_cold-logs.bats +++ b/tests/bats/40_cold-logs.bats @@ -10,16 +10,16 @@ fake_log() { } setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" # we reset config and data, and only run the daemon once for all the tests in this file ./instance-data load ./instance-crowdsec start - fake_log | "${CROWDSEC}" -dsn file:///dev/fd/0 -type syslog -no-api + fake_log | "${CROWDSEC}" -dsn file:///dev/fd/0 -type syslog -no-api 2>/dev/null } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/40_live-ban.bats b/tests/bats/40_live-ban.bats index 3ae9af53e..d78f43869 100644 --- a/tests/bats/40_live-ban.bats +++ b/tests/bats/40_live-ban.bats @@ -10,13 +10,13 @@ fake_log() { } setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" # we reset config and data, but run the daemon only in the tests that need it ./instance-data load } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { @@ -32,7 +32,8 @@ teardown() { @test "$FILE 1.1.1.172 has been banned" { tmpfile=$(TMPDIR="${BATS_TEST_TMPDIR}" mktemp) touch "${tmpfile}" - echo -e "---\nfilename: $tmpfile\nlabels:\n type: syslog\n" >>"${CONFIG_DIR}/acquis.yaml" + ACQUIS_YAML=$(config_yq '.crowdsec_service.acquisition_path') + echo -e "---\nfilename: $tmpfile\nlabels:\n type: syslog\n" >>"${ACQUIS_YAML}" ./instance-crowdsec start sleep 2 diff --git a/tests/bats/50_simulation.bats b/tests/bats/50_simulation.bats index 23c4af5e4..1a543987b 100644 --- a/tests/bats/50_simulation.bats +++ b/tests/bats/50_simulation.bats @@ -10,13 +10,13 @@ fake_log() { } setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" ./instance-data load ./instance-crowdsec start } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/70_http_plugin.bats b/tests/bats/70_http_plugin.bats index f769adf31..57b060886 100644 --- a/tests/bats/70_http_plugin.bats +++ b/tests/bats/70_http_plugin.bats @@ -4,7 +4,8 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" + # eval "$(debug)" ./instance-data load MOCK_OUT="${LOG_DIR}/mock-http.out" @@ -18,17 +19,17 @@ setup_file() { .url=strenv(MOCK_URL) | .group_wait="5s" | .group_threshold=2 - ' -i "${CONFIG_DIR}/notifications/http.yaml" + ' -i "$(config_yq '.config_paths.notification_dir')/http.yaml" yq ' .notifications=["http_default"] | .filters=["Alert.GetScope() == \"Ip\""] - ' -i "${CONFIG_DIR}/profiles.yaml" + ' -i "$(config_yq '.api.server.profiles_path')" yq ' .plugin_config.user="" | .plugin_config.group="" - ' -i "${CONFIG_DIR}/config.yaml" + ' -i "${CONFIG_YAML}" rm -f -- "${MOCK_OUT}" @@ -37,7 +38,7 @@ setup_file() { } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" ./instance-mock-http stop } diff --git a/tests/bats/71_dummy_plugin.bats b/tests/bats/71_dummy_plugin.bats index b25592f44..c4d3bd150 100644 --- a/tests/bats/71_dummy_plugin.bats +++ b/tests/bats/71_dummy_plugin.bats @@ -4,33 +4,34 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" + eval "$(debug)" ./instance-data load tempfile=$(TMPDIR="${BATS_FILE_TMPDIR}" mktemp) export tempfile - yq " - .group_wait=\"5s\" | + yq ' + .group_wait="5s" | .group_threshold=2 | - .output_file=\"${tempfile}\" - " -i "${CONFIG_DIR}/notifications/dummy.yaml" + .output_file=strenv(tempfile) + ' -i "$(config_yq '.config_paths.notification_dir')/dummy.yaml" yq ' .notifications=["dummy_default"] | .filters=["Alert.GetScope() == \"Ip\""] - ' -i "${CONFIG_DIR}/profiles.yaml" + ' -i "$(config_yq '.api.server.profiles_path')" yq ' .plugin_config.user="" | .plugin_config.group="" - ' -i "${CONFIG_DIR}/config.yaml" + ' -i "${CONFIG_YAML}" ./instance-crowdsec start } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/80_alerts.bats b/tests/bats/80_alerts.bats index 6874630fa..8153778ce 100644 --- a/tests/bats/80_alerts.bats +++ b/tests/bats/80_alerts.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/90_decisions.bats b/tests/bats/90_decisions.bats index 451852da7..a36aa921a 100644 --- a/tests/bats/90_decisions.bats +++ b/tests/bats/90_decisions.bats @@ -4,11 +4,11 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/97_ipv4_single.bats b/tests/bats/97_ipv4_single.bats index fab5d8a70..069583b50 100644 --- a/tests/bats/97_ipv4_single.bats +++ b/tests/bats/97_ipv4_single.bats @@ -4,7 +4,7 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" ./instance-data load ./instance-crowdsec start API_KEY=$(cscli bouncers add testbouncer -o raw) @@ -14,7 +14,7 @@ setup_file() { } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/97_ipv6_single.bats b/tests/bats/97_ipv6_single.bats index 2b546050a..89d40413e 100644 --- a/tests/bats/97_ipv6_single.bats +++ b/tests/bats/97_ipv6_single.bats @@ -4,7 +4,7 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" ./instance-data load ./instance-crowdsec start API_KEY=$(cscli bouncers add testbouncer -o raw) @@ -14,7 +14,7 @@ setup_file() { } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/98_ipv4_range.bats b/tests/bats/98_ipv4_range.bats index 0c7923ebb..0c2551a7e 100644 --- a/tests/bats/98_ipv4_range.bats +++ b/tests/bats/98_ipv4_range.bats @@ -4,7 +4,7 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" ./instance-data load ./instance-crowdsec start API_KEY=$(cscli bouncers add testbouncer -o raw) @@ -14,7 +14,7 @@ setup_file() { } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/98_ipv6_range.bats b/tests/bats/98_ipv6_range.bats index 61e6ffca3..6a0b04f34 100644 --- a/tests/bats/98_ipv6_range.bats +++ b/tests/bats/98_ipv6_range.bats @@ -4,7 +4,7 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" ./instance-data load ./instance-crowdsec start API_KEY=$(cscli bouncers add testbouncer -o raw) @@ -14,7 +14,7 @@ setup_file() { } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/99_lapi-stream-mode-scopes.bats b/tests/bats/99_lapi-stream-mode-scopes.bats index 168691d12..b4ec4d7ff 100644 --- a/tests/bats/99_lapi-stream-mode-scopes.bats +++ b/tests/bats/99_lapi-stream-mode-scopes.bats @@ -4,7 +4,7 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" ./instance-data load ./instance-crowdsec start API_KEY=$(cscli bouncers add testbouncer -o raw) @@ -14,7 +14,7 @@ setup_file() { } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { diff --git a/tests/bats/99_lapi-stream-mode.bats b/tests/bats/99_lapi-stream-mode.bats index dd102ad98..bd2dbb83d 100644 --- a/tests/bats/99_lapi-stream-mode.bats +++ b/tests/bats/99_lapi-stream-mode.bats @@ -4,7 +4,7 @@ set -u setup_file() { - load "../lib/setup_file.sh" >&3 2>&1 + load "../lib/setup_file.sh" ./instance-data load ./instance-crowdsec start API_KEY=$(cscli bouncers add testbouncer -o raw) @@ -14,7 +14,7 @@ setup_file() { } teardown_file() { - load "../lib/teardown_file.sh" >&3 2>&1 + load "../lib/teardown_file.sh" } setup() { @@ -71,4 +71,4 @@ api() { assert_output --partial '1111:2222:3333:4444:5555:6666:7777:8888' assert_output --partial '1.2.3.5' assert_output --partial '1.2.4.0/24' -} \ No newline at end of file +} diff --git a/tests/collect-hub-coverage b/tests/collect-hub-coverage index 46d8bdc5b..9bf82352c 100755 --- a/tests/collect-hub-coverage +++ b/tests/collect-hub-coverage @@ -15,7 +15,7 @@ TEST_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) hubdir="${LOCAL_DIR}/hub-tests" coverage() { - "${BIN_DIR}/cscli" --crowdsec "${BIN_DIR}/crowdsec" --cscli "${BIN_DIR}/cscli" hubtest coverage --"$1" --percent + "${CSCLI}" --crowdsec "${CROWDSEC}" --cscli "${CSCLI}" hubtest coverage --"$1" --percent } cd "$hubdir" || die "Could not find hub test results" diff --git a/tests/generate-hub-tests b/tests/generate-hub-tests index a9fa64f11..99fa9d2fc 100755 --- a/tests/generate-hub-tests +++ b/tests/generate-hub-tests @@ -7,13 +7,10 @@ TEST_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) # shellcheck source=./.environment.sh . "${TEST_DIR}/.environment.sh" -CSCLI="${BIN_DIR}/cscli" cscli() { - "${BIN_DIR}/cscli" "$@" + "${CSCLI}" "$@" } -CROWDSEC="${BIN_DIR}/crowdsec" - "${TEST_DIR}/instance-data" load hubdir="${LOCAL_DIR}/hub-tests" diff --git a/tests/instance-crowdsec b/tests/instance-crowdsec index bcd86e517..fa5d05506 100755 --- a/tests/instance-crowdsec +++ b/tests/instance-crowdsec @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -eu +script_name=$0 die() { echo >&2 "$@" @@ -8,7 +9,7 @@ die() { } about() { - die "usage: $0 [ start | stop ]" + die "usage: $script_name [ start | stop ]" } #shellcheck disable=SC1007 @@ -18,12 +19,12 @@ THIS_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) # you have not removed set -u above, have you? -[ -z "${BIN_DIR-}" ] && die "\$BIN_DIR must be defined." +[ -z "${CROWDSEC-}" ] && die "\$CROWDSEC must be defined." [ -z "${LOG_DIR-}" ] && die "\$LOG_DIR must be defined." [ -z "${PID_DIR-}" ] && die "\$PID_DIR must be defined." -if [ ! -e "${BIN_DIR}/crowdsec" ]; then - die "${BIN_DIR}/crowdsec is missing. Please run 'make bats-build' to create it." +if [ ! -f "${CROWDSEC}" ]; then + die "${CROWDSEC} is missing. Please build (with 'make bats-build') or install it." fi wait_for_port() { @@ -51,7 +52,7 @@ DAEMON_PID=${PID_DIR}/crowdsec.pid start_instance() { OUT_FILE="${LOG_DIR}/crowdsec.out" \ DAEMON_PID="${DAEMON_PID}" \ - "${TEST_DIR}/run-as-daemon" "${BIN_DIR}/crowdsec" + "${TEST_DIR}/run-as-daemon" "${CROWDSEC}" wait_for_port 6060 } diff --git a/tests/instance-data b/tests/instance-data index 1980cb4ee..eb24acf39 100755 --- a/tests/instance-data +++ b/tests/instance-data @@ -9,7 +9,7 @@ die() { } about() { - die "usage: $0 [make | load | clean]" + die "usage: $script_name [make | load | clean]" } #shellcheck disable=SC1007 @@ -22,38 +22,38 @@ cd "${THIS_DIR}" [ -z "${TEST_DIR-}" ] && die "\$TEST_DIR must be defined." [ -z "${LOCAL_DIR-}" ] && die "\$LOCAL_DIR must be defined." -[ -z "${BIN_DIR-}" ] && die "\$BIN_DIR must be defined." -[ -z "${CONFIG_DIR-}" ] && die "\$CONFIG_DIR must be defined." -[ -z "${DATA_DIR-}" ] && die "\$DATA_DIR must be defined." +[ -z "${CSCLI-}" ] && die "\$CSCLI must be defined." [ -z "${LOCAL_INIT_DIR-}" ] && die "\$LOCAL_INIT_DIR must be defined." [ -z "${PLUGIN_DIR-}" ] && die "\$PLUGIN_DIR must be defined." -if [ ! -e "${BIN_DIR}/cscli" ]; then - die "${BIN_DIR}/cscli is missing. Please run 'make bats-build' to create it." +if [ ! -f "${CSCLI}" ]; then + die "${CSCLI} is missing. Please build (with 'make bats-build') or install it." fi -# fails if config_dir or data_dir are not subpaths of local_dir -REL_CONFIG_DIR=${CONFIG_DIR#$LOCAL_DIR} -REL_CONFIG_DIR=${REL_CONFIG_DIR#/} -REL_DATA_DIR=${DATA_DIR#$LOCAL_DIR} -REL_DATA_DIR=${REL_DATA_DIR#/} +REL_CONFIG_DIR="etc/crowdsec" +REL_DATA_DIR="var/lib/crowdsec/data" + +DATA_DIR="${LOCAL_DIR}/${REL_DATA_DIR}" +export DATA_DIR +CONFIG_DIR="${LOCAL_DIR}/${REL_CONFIG_DIR}" +export CONFIG_DIR remove_init_data() { - rm -rf -- "${CONFIG_DIR:?}"/* "${DATA_DIR:?}"/* + rm -rf -- "${LOCAL_DIR:?}/${REL_CONFIG_DIR}"/* "${LOCAL_DIR:?}/${REL_DATA_DIR:?}"/* } config_generate() { - cp ../config/acquis.yaml "${CONFIG_DIR}/" - cp ../config/profiles.yaml "${CONFIG_DIR}/" - cp ../config/simulation.yaml "${CONFIG_DIR}/" - cp ../config/local_api_credentials.yaml "${CONFIG_DIR}/" - cp ../config/online_api_credentials.yaml "${CONFIG_DIR}/" + mkdir -p "${CONFIG_DIR}" - cp ../plugins/notifications/http/http.yaml "${CONFIG_DIR}/notifications/" - cp ../plugins/notifications/email/email.yaml "${CONFIG_DIR}/notifications/" - cp ../plugins/notifications/slack/slack.yaml "${CONFIG_DIR}/notifications/" - cp ../plugins/notifications/splunk/splunk.yaml "${CONFIG_DIR}/notifications/" - cp ../plugins/notifications/dummy/dummy.yaml "${CONFIG_DIR}/notifications/" + cp ../config/acquis.yaml \ + ../config/profiles.yaml \ + ../config/simulation.yaml \ + ../config/local_api_credentials.yaml \ + ../config/online_api_credentials.yaml \ + "${CONFIG_DIR}/" + + cp ../plugins/notifications/*/{http,email,slack,splunk,dummy}.yaml \ + "${CONFIG_DIR}/notifications/" yq ' .common.daemonize=false | @@ -78,23 +78,32 @@ config_generate() { make_init_data() { remove_init_data + mkdir -p "${DATA_DIR}" mkdir -p "${CONFIG_DIR}/notifications" config_generate mkdir -p "${CONFIG_DIR}/hub" - "${BIN_DIR}/cscli" machines add githubciXXXXXXXXXXXXXXXXXXXXXXXX --auto - "${BIN_DIR}/cscli" capi register - "${BIN_DIR}/cscli" hub update - "${BIN_DIR}/cscli" collections install crowdsecurity/linux + "${CSCLI}" machines add githubciXXXXXXXXXXXXXXXXXXXXXXXX --auto + "${CSCLI}" capi register + "${CSCLI}" hub update + "${CSCLI}" collections install crowdsecurity/linux mkdir -p "${CONFIG_DIR}/patterns" cp -ax "../config/patterns" "${CONFIG_DIR}/" "${TEST_DIR}/instance-crowdsec" start - "${BIN_DIR}/cscli" lapi status + "${CSCLI}" lapi status "${TEST_DIR}/instance-crowdsec" stop - tar -C "${LOCAL_DIR}" --create --file "${LOCAL_INIT_DIR}/init-config-data.tar" "$REL_CONFIG_DIR" "$REL_DATA_DIR" + # we deal with the database separately (might be mysql, postgres) + + mkdir -p "${LOCAL_INIT_DIR}" + + ./instance-db backup "${LOCAL_INIT_DIR}/database" + + tar -C "${LOCAL_DIR}" --create \ + --exclude "$REL_DATA_DIR"/crowdsec.db \ + --file "${LOCAL_INIT_DIR}/init-config-data.tar" "$REL_CONFIG_DIR" "$REL_DATA_DIR" remove_init_data } @@ -107,6 +116,7 @@ load_init_data() { remove_init_data tar -C "${LOCAL_DIR}" --extract --file "${LOCAL_INIT_DIR}/init-config-data.tar" + ./instance-db restore "${LOCAL_INIT_DIR}/database" } diff --git a/tests/instance-db b/tests/instance-db new file mode 100755 index 000000000..3bc7d2537 --- /dev/null +++ b/tests/instance-db @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +#shellcheck disable=SC1007 +THIS_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +cd "${THIS_DIR}" + +./instance-sqlite "$@" diff --git a/tests/instance-mock-http b/tests/instance-mock-http index 136709ca2..af88d1885 100755 --- a/tests/instance-mock-http +++ b/tests/instance-mock-http @@ -51,7 +51,7 @@ start_instance() { DAEMON_PID="${DAEMON_PID}" \ "${TEST_DIR}/run-as-daemon" /usr/bin/env python3 -u "${THIS_DIR}/mock-http.py" "$1" wait_for_port "$1" - echo "mock http started on port $1" +# echo "mock http started on port $1" } stop_instance() { diff --git a/tests/instance-sqlite b/tests/instance-sqlite new file mode 100755 index 000000000..6fa33d13f --- /dev/null +++ b/tests/instance-sqlite @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -eu +script_name=$0 + +die() { + echo >&2 "$@" + exit 1 +} + +about() { + die "usage: $script_name [backup | restore] " +} + +#shellcheck disable=SC1007 +THIS_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +cd "${THIS_DIR}" +#shellcheck disable=SC1090 +. ./.environment.sh + +# you have not removed set -u above, have you? + +[ -z "${CONFIG_YAML-}" ] && die "\$CONFIG_YAML must be defined." + +# --------------------------- + +[ $# -lt 1 ] && about + +./assert-crowdsec-not-running + +DATA_DIR=$(yq <"${CONFIG_YAML}" '.config_paths.data_dir') +DB_FILE="${DATA_DIR}/crowdsec.db" + +case "$1" in + backup) + [ $# -lt 2 ] && about + backup_file="$2" + # dirty fast cp. nothing should be accessing it right now, anyway. + [ -f "${DB_FILE}" ] || die "missing file ${DB_FILE}" + cp "${DB_FILE}" "$backup_file" + ;; + restore) + [ $# -lt 2 ] && about + backup_file="$2" + [ -f "$backup_file" ] || die "missing file $backup_file" + cp "$backup_file" "${DB_FILE}" + ;; + *) + about + ;; +esac; + diff --git a/tests/lib/setup_file.sh b/tests/lib/setup_file.sh index 73dd185c3..19d03cd57 100644 --- a/tests/lib/setup_file.sh +++ b/tests/lib/setup_file.sh @@ -1,9 +1,20 @@ +debug() { + echo 'exec 1<&-; exec 2<&-; exec 1>&3; exec 2>&1' +} +export -f debug + +# redirects stdout and stderr to &3 otherwise the errors in setup, teardown would +# go unreported. +# BUT - don't do this in test functions. Everything written to stdout and +# stderr after this line will go to the terminal, but in the tests, these +# are supposed to be collected and shown only in case of test failure +# (see options --print-output-on-failure and --show-output-of-passing-tests) +eval "$(debug)" + # Allow tests to use relative paths for helper scripts. -# Must redirect output to &3 otherwise errors in setup_file, teardown_file go unreported - # shellcheck disable=SC2164 -cd "${TEST_DIR}" >&3 2>&1 +cd "${TEST_DIR}" # complain if there's a crowdsec running system-wide or leftover from a previous test ./assert-crowdsec-not-running @@ -13,10 +24,8 @@ FILE="$(basename "${BATS_TEST_FILENAME}" .bats):" export FILE # the variables exported here can be seen in other setup/teardown/test functions -CROWDSEC="${BIN_DIR}/crowdsec" -export CROWDSEC -CSCLI="${BIN_DIR}/cscli" -export CSCLI +# MYVAR=something +# export MYVAR # functions too cscli() { @@ -24,6 +33,11 @@ cscli() { } export -f cscli +config_yq() { + yq <"${CONFIG_YAML}" "$@" +} +export -f config_yq + # We use these functions like this: # somecommand <(stderr) # to provide a standard input to "somecommand". @@ -43,3 +57,4 @@ output() { printf '%s' "$output" } export -f output + diff --git a/tests/lib/teardown_file.sh b/tests/lib/teardown_file.sh index 06f7ab680..2d9287980 100644 --- a/tests/lib/teardown_file.sh +++ b/tests/lib/teardown_file.sh @@ -1,4 +1,7 @@ +# any stdout, stderr from now on will go to &3 +eval "$(debug)" + # ensure we don't leave crowdsec running if tests are broken or interrupted ./instance-crowdsec stop