func tests improvements (#2759)
* faster reload test * decode-jwt script * replace 'netcat' requirement with python script * fix lapi status test
This commit is contained in:
parent
6ffb68322f
commit
ce32fc019e
13 changed files with 102 additions and 49 deletions
2
.github/workflows/bats-hub.yml
vendored
2
.github/workflows/bats-hub.yml
vendored
|
@ -42,7 +42,7 @@ jobs:
|
|||
env:
|
||||
GOBIN: /usr/local/bin
|
||||
run: |
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq netcat-openbsd libre2-dev
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq libre2-dev
|
||||
|
||||
- name: "Build crowdsec and fixture"
|
||||
run: make bats-clean bats-build bats-fixture BUILD_STATIC=1
|
||||
|
|
2
.github/workflows/bats-mysql.yml
vendored
2
.github/workflows/bats-mysql.yml
vendored
|
@ -49,7 +49,7 @@ jobs:
|
|||
env:
|
||||
GOBIN: /usr/local/bin
|
||||
run: |
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq netcat-openbsd libre2-dev
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq libre2-dev
|
||||
|
||||
- name: "Build crowdsec and fixture"
|
||||
run: |
|
||||
|
|
2
.github/workflows/bats-postgres.yml
vendored
2
.github/workflows/bats-postgres.yml
vendored
|
@ -58,7 +58,7 @@ jobs:
|
|||
env:
|
||||
GOBIN: /usr/local/bin
|
||||
run: |
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq netcat-openbsd libre2-dev
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq libre2-dev
|
||||
|
||||
- name: "Build crowdsec and fixture (DB_BACKEND: pgx)"
|
||||
run: |
|
||||
|
|
2
.github/workflows/bats-sqlite-coverage.yml
vendored
2
.github/workflows/bats-sqlite-coverage.yml
vendored
|
@ -39,7 +39,7 @@ jobs:
|
|||
env:
|
||||
GOBIN: /usr/local/bin
|
||||
run: |
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq netcat-openbsd libre2-dev
|
||||
sudo apt -qq -y -o=Dpkg::Use-Pty=0 install build-essential daemonize jq libre2-dev
|
||||
|
||||
- name: "Build crowdsec and fixture"
|
||||
run: |
|
||||
|
|
|
@ -63,7 +63,6 @@ architectures.
|
|||
- `jq`
|
||||
- `nc`
|
||||
- `openssl`
|
||||
- `openbsd-netcat`
|
||||
- `python3`
|
||||
|
||||
## Running all tests
|
||||
|
|
|
@ -18,7 +18,7 @@ installation and run the tests, or run the playbooks separately to iterate while
|
|||
|
||||
- run-all.yml: run the other playbooks in the correct order.
|
||||
|
||||
- provision-dependencies.yml: install the bats requirements (bash, netcat, cfssl, etc.), compilers, and database.
|
||||
- provision-dependencies.yml: install the bats requirements (bash, cfssl, etc.), compilers, and database.
|
||||
|
||||
- provision-test-suite.yml: install the tests scripts and bats environment, and the crowdsec sources if we want to build the `crowdsec under test`.
|
||||
|
||||
|
|
|
@ -3,5 +3,5 @@ unset IFS
|
|||
set -euf
|
||||
|
||||
# coreutils -> for timeout (busybox is not enough)
|
||||
sudo apk add python3 go tar procps netcat-openbsd coreutils
|
||||
sudo apk add python3 go tar procps coreutils
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
sudo emerge --quiet app-portage/gentoolkit dev-vcs/git net-misc/curl app-misc/jq net-analyzer/openbsd-netcat
|
||||
sudo emerge --quiet app-portage/gentoolkit dev-vcs/git net-misc/curl app-misc/jq
|
||||
|
|
|
@ -84,7 +84,7 @@ teardown() {
|
|||
|
||||
config_disable_agent
|
||||
|
||||
sleep 5
|
||||
sleep 2
|
||||
|
||||
rune -0 kill -HUP "$PID"
|
||||
|
||||
|
@ -107,13 +107,13 @@ teardown() {
|
|||
assert_file_contains "$log_old" "Bucket routine exiting"
|
||||
assert_file_contains "$log_old" "serve: shutting down api server"
|
||||
|
||||
sleep 5
|
||||
sleep 2
|
||||
|
||||
assert_file_exists "$log_new"
|
||||
|
||||
for ((i=0; i<10; i++)); do
|
||||
sleep 1
|
||||
grep -q "Reload is finished" <"$log_old" && break
|
||||
grep -q "Reload is finished" <"$log_new" && break
|
||||
done
|
||||
|
||||
echo "waited $i seconds"
|
||||
|
|
|
@ -80,7 +80,6 @@ teardown() {
|
|||
|
||||
@test "lapi status shouldn't be ok without api.server" {
|
||||
config_disable_lapi
|
||||
./instance-crowdsec start || true
|
||||
rune -1 cscli machines list
|
||||
assert_stderr --partial "local API is disabled -- this command must be run on the local API machine"
|
||||
}
|
||||
|
|
|
@ -36,12 +36,6 @@ check_jq() {
|
|||
fi
|
||||
}
|
||||
|
||||
check_nc() {
|
||||
if ! command -v nc >/dev/null; then
|
||||
die "missing required program 'nc' (package 'netcat-openbsd')"
|
||||
fi
|
||||
}
|
||||
|
||||
check_base64() {
|
||||
if ! command -v base64 >/dev/null; then
|
||||
die "missing required program 'base64'"
|
||||
|
@ -66,7 +60,6 @@ check_bats_core
|
|||
check_curl
|
||||
check_daemonizer
|
||||
check_jq
|
||||
check_nc
|
||||
check_base64
|
||||
check_python3
|
||||
check_pkill
|
||||
|
|
40
test/bin/decode-jwt
Executable file
40
test/bin/decode-jwt
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import base64
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
def decode_base64url(data):
|
||||
# Not the same as "bin/base64 -d":
|
||||
# + -> -
|
||||
# / -> _
|
||||
# = -> ''
|
||||
pad = len(data) % 4
|
||||
if pad > 0:
|
||||
data += '=' * (4 - pad)
|
||||
return base64.urlsafe_b64decode(data)
|
||||
|
||||
|
||||
def decode_jwt(token):
|
||||
token = token.rstrip('\n')
|
||||
header, payload, signature = token.split('.')
|
||||
decoded_header = json.loads(decode_base64url(header))
|
||||
decoded_payload = json.loads(decode_base64url(payload))
|
||||
# the signature is binary, so we don't decode it
|
||||
|
||||
return decoded_header, decoded_payload, signature
|
||||
|
||||
|
||||
def main():
|
||||
header, payload, signature = decode_jwt(sys.stdin.read())
|
||||
out = {
|
||||
'header': header,
|
||||
'payload': payload,
|
||||
'signature': signature,
|
||||
}
|
||||
print(json.dumps(out, indent=4))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,42 +1,64 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env python3
|
||||
|
||||
set -eu
|
||||
import argparse
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
|
||||
script_name=$0
|
||||
initial_interval = 0.02
|
||||
max_interval = 0.5
|
||||
|
||||
die() {
|
||||
echo >&2 "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
about() {
|
||||
die "usage: ${script_name} [-q] <port_number>"
|
||||
}
|
||||
def is_fd_open(fd):
|
||||
try:
|
||||
os.fstat(fd)
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
[[ $# -lt 1 ]] && about
|
||||
|
||||
QUIET=
|
||||
if [[ "$1" == "-q" ]]; then
|
||||
QUIET=quiet
|
||||
shift
|
||||
fi
|
||||
# write to file descriptor 3 if it is open (during bats tests), otherwise stderr
|
||||
def write_error(ex):
|
||||
fd = 2
|
||||
if is_fd_open(3):
|
||||
fd = 3
|
||||
os.write(fd, str(ex).encode())
|
||||
|
||||
[[ $# -lt 1 ]] && about
|
||||
|
||||
port_number=$1
|
||||
def wait(host, port, timeout):
|
||||
t0 = time.perf_counter()
|
||||
current_interval = initial_interval
|
||||
while True:
|
||||
try:
|
||||
with socket.create_connection((host, port), timeout=timeout):
|
||||
break
|
||||
except OSError as ex:
|
||||
if time.perf_counter() - t0 >= timeout:
|
||||
raise TimeoutError(f'Timeout waiting for {host}:{port} after {timeout}s') from ex
|
||||
time.sleep(current_interval)
|
||||
current_interval = min(current_interval * 1.5, max_interval)
|
||||
|
||||
# 4 seconds may seem long, but the tests must work on embedded, slow arm boxes too
|
||||
for _ in $(seq 40); do
|
||||
nc -z localhost "${port_number}" >/dev/null 2>&1 && exit 0
|
||||
sleep .1
|
||||
done
|
||||
|
||||
# send to &3 if open
|
||||
if { true >&3; } 2>/dev/null; then
|
||||
[[ -z "${QUIET}" ]] && echo "Can't connect to port ${port_number}" >&3
|
||||
else
|
||||
[[ -z "${QUIET}" ]] && echo "Can't connect to port ${port_number}" >&2
|
||||
fi
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser(description="Check if a port is open.")
|
||||
parser.add_argument("port", type=int, help="Port number to check")
|
||||
parser.add_argument("--host", type=str, default="localhost", help="Host to check")
|
||||
parser.add_argument("-t", "--timeout", type=float, default=10.0, help="Timeout duration in seconds")
|
||||
parser.add_argument("-q", "--quiet", action="store_true", help="Enable quiet mode")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
exit 1
|
||||
try:
|
||||
wait(args.host, args.port, args.timeout)
|
||||
except TimeoutError as ex:
|
||||
if not args.quiet:
|
||||
write_error(ex)
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.exit(0)
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
|
Loading…
Reference in a new issue