Skip to content

Commit 373bf66

Browse files
authored
update test/README.md (#3652)
* update test/README.md * make targets: bats-mysql, bats-postgres
1 parent 37c35ee commit 373bf66

File tree

3 files changed

+101
-104
lines changed

3 files changed

+101
-104
lines changed

test/README.md

Lines changed: 81 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,86 @@
11

22
# What is this?
33

4-
This directory contains scripts for functional testing. The tests are run with
5-
the [bats-core](https://github.com/bats-core/bats-core) framework, which is an
6-
active fork of the older BATS (Bash Automated Testing System).
4+
This directory contains scripts for functional testing. They complement
5+
the unit tests and provide an environment that can be used during development
6+
as well.
7+
8+
The tests are run with the [bats-core](https://github.com/bats-core/bats-core)
9+
framework, which is provided as git submodules in the crowdsec repository.
710

811
With the addition of [the ansible playbooks](ansible/README.md) it is possible
912
to use VMs to test the binary packages, service management and other CPU
1013
architectures.
1114

12-
### cscli
13-
14-
| Feature | Covered | Notes |
15-
| :-------------------- | :----------------- | :------------------------- |
16-
| `cscli alerts` | - | |
17-
| `cscli bouncers` | `10_bouncers` | |
18-
| `cscli capi` | `01_base` | `status` only |
19-
| `cscli collections` | `20_collections` | |
20-
| `cscli config` | `01_base` | minimal testing (no crash) |
21-
| `cscli dashboard` | - | docker inside docker 😞 |
22-
| `cscli decisions` | `9[78]_ipv[46]*` | |
23-
| `cscli hub` | `dyn_bats/99_hub` | |
24-
| `cscli lapi` | `01_base` | |
25-
| `cscli machines` | `30_machines` | |
26-
| `cscli metrics` | - | |
27-
| `cscli parsers` | - | |
28-
| `cscli postoverflows` | - | |
29-
| `cscli scenarios` | - | |
30-
| `cscli simulation` | `50_simulation` | |
31-
| `cscli version` | `01_base` | |
32-
33-
### crowdsec
34-
35-
| Feature | Covered | Notes |
36-
| :----------------------------- | :------------- | :----------------------------------------- |
37-
| `systemctl` start/stop/restart | - | |
38-
| agent behavior | `40_live-ban` | minimal testing (simple ssh-bf detection) |
39-
| forensic mode | `40_cold-logs` | minimal testing (simple ssh-bf detection) |
40-
| starting without LAPI | `02_nolapi` | |
41-
| starting without agent | `03_noagent` | |
42-
| starting without CAPI | `04_nocapi` | |
43-
| prometheus testing | - | |
44-
45-
### API
46-
47-
| Feature | Covered | Notes |
48-
| :----------------- | :--------------- | :----------- |
49-
| alerts GET/POST | `9[78]_ipv[46]*` | |
50-
| decisions GET/POST | `9[78]_ipv[46]*` | |
51-
| stream mode | `99_lapi-stream-mode | |
52-
53-
5415
# How to use it
5516

5617
## pre-requisites
5718

58-
- `git submodule init; git submodule update`
59-
- `base64`
60-
- `bash>=4.4`
61-
- `curl`
62-
- `daemonize`
63-
- `jq`
64-
- `python3`
19+
(for building crowdsec)
20+
21+
- `go`
22+
- `pkg-config`
23+
- `re2`
24+
25+
On Ubuntu/Debian, you can install the above with:
26+
27+
```console
28+
$ sudo apt install pkgconf golang-go libre2-dev
29+
...
30+
```
31+
32+
(for the test suite)
33+
34+
- `git submodule init; git submodule update`
35+
- `bash>=4.4`
36+
- `curl`
37+
- `daemonize`
38+
- `jq`
39+
- `python3`
40+
41+
These can be installed with
42+
43+
```console
44+
$ sudo apt install bash curl daemonize jq python3
45+
...
46+
```
47+
48+
Additional dependencies are required if you need to test with mysql or postgres
49+
(see below).
6550

66-
## Running all tests
51+
## Running the tests
6752

6853
Run `make clean bats-all` to perform a test build + run.
69-
To repeat test runs without rebuilding crowdsec, use `make bats-test`.
7054

55+
If a test is failing, you can run only the script that contains it with
56+
57+
```console
58+
$ ./test/run-tests test/bats/<script>.bats
59+
...
60+
```
61+
62+
After changing the code, rebuild the binaries with `make bats-build` and re-run
63+
the test to verify.
7164

72-
## Debugging tests
65+
Most tests are isolated, you don't need to run all the script:
66+
see `./test/run-tests --help` for all the options.
7367

74-
See `./test/run-tests --help` to run/debug specific tests.
68+
Example: `./test/run-tests test/bats/02_nolapi.bats -f "cscli config backup"`
69+
(the string is a regexp).
70+
You need to provide a path for a test file or directory (even if it's the full 'test/bats')
71+
to use the `-f` option.
7572

76-
Example: `./test/run-tests test/bats/02_nolapi.bats -f "cscli config backup"` (the string is a regexp).
77-
You need to provide a path for a test file or directory (even if it's the full 'test/bats') to use the `-f` option.
73+
Keep in mind that some of the files in test/bats are meant as a "test suite" so
74+
the individual tests will fail when run in isolation, or out of order.
7875

76+
Do not attempt to run the functional tests in parallel since they reuse
77+
the same file locations.
7978

80-
# How does it work?
79+
# Writing tests
8180

8281
In BATS, you write tests in the form of Bash functions that have unique
8382
descriptions (the name of the test). You can do most things that you can
84-
normally do in a shell function. If there is any error condition, the test
83+
normally do in a shell function. When an error is encountered, the test
8584
fails. A set of functions is provided to implement assertions, and a mechanism
8685
of `setup`/`teardown` is provided at the level of individual tests (functions)
8786
or group of tests (files).
@@ -104,24 +103,15 @@ If you do that, please remove it once the test development is finished, because
104103
this practice breaks the TAP protocol (unless each line has a '#' as first
105104
character, but really, it's better to avoid unnecessary output when tests succeed).
106105

107-
You can find here the documentation for the main framework and the plugins we use in this test suite:
108-
109-
- [bats-core tutorial](https://bats-core.readthedocs.io/en/stable/tutorial.html)
110-
- [Writing tests](https://bats-core.readthedocs.io/en/stable/writing-tests.html)
111-
- [bats-assert](https://github.com/bats-core/bats-assert)
112-
- [bats-support](https://github.com/bats-core/bats-support)
113-
- [bats-file](https://github.com/bats-core/bats-file)
114-
- [bats-mock](https://github.com/grayhemp/bats-mock)
115-
116-
> As it often happens with open source, the first results from search engines refer to the old, unmaintained forks.
117-
> Be sure to use the links above to find the good versions.
118-
119-
Since bats-core is [TAP (Test Anything Protocol)](https://testanything.org/)
120-
compliant, its output is in a standardized format. It can be integrated with a
121-
separate [tap reporter](https://www.npmjs.com/package/tape#pretty-reporters) or
122-
included in a larger test suite. The TAP specification is pretty minimalist and
123-
some glue may be needed.
106+
You can find here the documentation for the main framework and the plugins
107+
we use in this test suite:
124108

109+
- [bats-core tutorial](https://bats-core.readthedocs.io/en/stable/tutorial.html)
110+
- [Writing tests](https://bats-core.readthedocs.io/en/stable/writing-tests.html)
111+
- [bats-assert](https://github.com/bats-core/bats-assert)
112+
- [bats-support](https://github.com/bats-core/bats-support)
113+
- [bats-file](https://github.com/bats-core/bats-file)
114+
- [bats-mock](https://github.com/grayhemp/bats-mock)
125115

126116
# setup and teardown
127117

@@ -200,7 +190,6 @@ But.. there is a but. Quoting from [the FAQ](https://bats-core.readthedocs.io/en
200190
201191
This doesn't mean you can't do that, just that you're on your own if the is an error.
202192

203-
204193
# Testing crowdsec
205194

206195
## Fixtures
@@ -224,7 +213,7 @@ To set up the installation described above we provide a couple of scripts,
224213
processes; they are meant to be used in setup/teardown in several ways,
225214
according to the specific needs of the group of tests in the file.
226215

227-
- `instance-data make`
216+
- `instance-data make`
228217

229218
Creates a tar file in `./local-init/init-config-data.tar`.
230219
The file contains all the configuration, hub and database files needed
@@ -233,33 +222,32 @@ according to the specific needs of the group of tests in the file.
233222
install crowdsecurity/linux` are executed here so they don't need to be
234223
repeated for each test or group of tests.
235224

236-
- `instance-data load`
225+
- `instance-data load`
237226

238227
Extracts the files created by `instance-data make` for use by the local
239228
crowdsec instance. Crowdsec must not be running while this operation is
240229
performed.
241230

242-
- instance-data lock/unlock
231+
- instance-data lock/unlock
243232

244233
When playing around with a local crowdsec installation, you can run "instance-data lock"
245234
to prevent the bats suite from running, so it won't overwrite your configuration or data.
246235

247-
- `instance-crowdsec [ start | stop ]`
236+
- `instance-crowdsec [ start | stop ]`
248237

249238
Runs (or stops) crowdsec as a background process. PID and lockfiles are
250239
written in `./local/var/run/`.
251240

252-
253241
Here are some ways to use these two scripts.
254242

255-
- case 1: load a fresh crowsec instance + data for each test (01_base, 10_bouncers, 20_collections...)
243+
- case 1: load a fresh crowdsec instance + data for each test (01_base, 10_bouncers, 20_collections...)
256244

257245
This offers the best isolation, but the tests run slower. More importantly,
258246
since there is no concept of "grouping" tests in bats-core with the exception
259247
of files, if you need to perform some setup that is common to two or more
260248
tests, you will have to repeat the code.
261249

262-
- case 2: load a fresh set of data for each test, but run crowdsec only for
250+
- case 2: load a fresh set of data for each test, but run crowdsec only for
263251
the tests that need it, possibly after altering the configuration
264252
(02_nolapi, 03_noagent, 04_nocapi, 40_live-ban)
265253

@@ -268,14 +256,13 @@ Here are some ways to use these two scripts.
268256
configuration inside the test function before running the lapi/agent. See
269257
how we use `yq` to change the YAML files to that effect.
270258

271-
- case 3: start crowdsec with the initial set of configuration+data once, and keep it
259+
- case 3: start crowdsec with the initial set of configuration+data once, and keep it
272260
running for all the tests (50_simulation, 98_ipv4, 98_ipv6)
273261

274262
This offers no isolation across tests, which over time could break more
275263
often as result, but you can rely on the test order to test more complex
276264
scenarios with a reasonable performance and the least amount of code.
277265

278-
279266
## status, stdout and stderr
280267

281268
As we said, if any error occurs inside a test function, the test
@@ -326,10 +313,10 @@ to record and assert which parameters are passed to it.
326313

327314
## gotchas
328315

329-
- pay attention to tests that are not run - for example "bats warning: Executed 143
316+
- pay attention to tests that are not run - for example "bats warning: Executed 143
330317
instead of expected 144 tests". They are especially tricky to debug.
331318

332-
- using the `load` command in `teardown()` causes tests to be silently skipped or break in "funny"
319+
- using the `load` command in `teardown()` causes tests to be silently skipped or break in "funny"
333320
ways. The other functions seem safe.
334321

335322
# Testing with MySQL and Postgres
@@ -346,7 +333,7 @@ Run Postgres somewhere, version 10 or above - easy to do in a docker container.
346333
You also need to install a postgresql-client package or equivalent, to provide
347334
recent pg_dump and pg_restore executables (not older than the PG version in the docker container).
348335

349-
```
336+
```console
350337
$ sudo docker run --detach --name=postgres -p 5432:5432 --env="POSTGRES_PASSWORD=postgres" postgres:latest
351338
```
352339

@@ -386,24 +373,23 @@ A mysql-client package is required as well.
386373

387374
## troubleshooting
388375

389-
- CAPI is disabled, why?
376+
- CAPI is disabled, why?
390377
Most tests don't need it. Helper scripts are provided in `test/enable-capi`
391378
and `test/disable-capi` for interactive use, and two library functions
392379
`config_enable_capi` and `config_disable_capi` to call inside the tests.
393380
You still need to call `cscli capi register` after enabling it.
394381

395-
- My tests are hanging forever, why?
382+
- My tests are hanging forever, why?
396383
See if you have a jq/yq or similar process waiting for standard input. Hint:
397384
you can pass a file from the result of the previous `run` command with
398385
`<(output)`. This substitutes the expression with a file name, but if you
399386
really want it in standard input, you have to use `< <(output)`. Bash is
400387
awesome but the syntax is often weird.
401388

402-
- I can't do X with jq.
389+
- I can't do X with jq.
403390
If you prefer you can use yq. It can parse and generate json, and it has a
404391
different syntax.
405392

406-
- I get "while parsing /tmp/....: yaml: line 5: mapping values are not allowed in this context"
393+
- I get "while parsing /tmp/....: yaml: line 5: mapping values are not allowed in this context"
407394
Check the heredocs (the <<EOT blocks). Each line must start with a hard TAB
408395
followed by spaces. You are probably missing some tabs.
409-

test/bats.mk

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ bats-environment:
6666
bats-check-requirements: ## Check dependencies for functional tests
6767
@$(TEST_DIR)/bin/check-requirements
6868

69-
bats-update-tools: ## Install/update tools required for functional tests
69+
bats-tools: ## Install/update tools required for functional tests
7070
# yq v4.44.3
7171
GOBIN=$(TEST_DIR)/tools go install github.com/mikefarah/yq/v4@bbdd97482f2d439126582a59689eb1c855944955
7272
# cfssl v1.6.5
@@ -86,7 +86,7 @@ bats-build: bats-environment ## Build binaries for functional tests
8686
@install -m 0755 cmd/notification-*/notification-* $(BATS_PLUGIN_DIR)/
8787

8888
# Create a reusable package with initial configuration + data
89-
bats-fixture: bats-check-requirements bats-update-tools ## Build fixture for functional tests
89+
bats-fixture: bats-check-requirements bats-tools ## Build fixture for functional tests
9090
@echo "Creating functional test fixture."
9191
@$(TEST_DIR)/instance-data make
9292

@@ -109,3 +109,21 @@ bats-lint: ## Static checks for the test scripts.
109109
bats-test-package: bats-environment ## CI only - test a binary package (deb, rpm, ...)
110110
$(TEST_DIR)/instance-data make
111111
$(TEST_DIR)/run-tests $(TEST_DIR)/bats
112+
113+
.PHONY: .bats-mysql
114+
bats-mysql: ## Start a mysql container
115+
docker run -d \
116+
--name mysql \
117+
-e MYSQL_ROOT_PASSWORD=secret \
118+
-p 3306:3306 \
119+
docker.io/library/mysql:8.0 \
120+
--default-authentication-plugin=mysql_native_password
121+
122+
.PHONY: .bats-postgres
123+
bats-postgres: ## Start a postgres container
124+
docker run -d \
125+
--name postgres \
126+
-e POSTGRES_PASSWORD=secret \
127+
-p 5432:5432 \
128+
docker.io/library/postgres:17
129+

test/bin/check-requirements

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@ check_jq() {
3636
fi
3737
}
3838

39-
check_base64() {
40-
if ! command -v base64 >/dev/null; then
41-
die "missing required program 'base64'"
42-
fi
43-
}
44-
4539
check_pkill() {
4640
if ! command -v pkill >/dev/null; then
4741
die "missing required program 'pkill'"
@@ -60,6 +54,5 @@ check_bats_core
6054
check_curl
6155
check_daemonizer
6256
check_jq
63-
check_base64
6457
check_python3
6558
check_pkill

0 commit comments

Comments
 (0)