Introduce bash scripting unittests (#724)
### Description of the change This adds an environment for unit testing our bash scripts, using [BATS](https://github.com/bats-core/bats-core). It implements first tests for `config_environment.sh`. ### Benefits Writing unit tests for bash scripts documents the expected behavior and allows it being a quality gate in our CI. ### Possible drawbacks Not everyone is familiar with this approach and unit testing framework. Me neither, it took me some hours to get into it. ### Applicable issues - Related to #691 where an issue in `config_environment.sh` was detected. It doesn't fixes it yet. This will be a dedicated Pull Request. ### Additional information I've verified that the changes for Renovate are indeed working. You may wonder why there is only one `run $PROJECT_ROOT/scripts/init-containers/config/config_environment.sh` and many `run execute_test_script` calls. Usually, testing a script itself would be executing `run $PROJECT_ROOT/scripts/init-containers/config/config_environment.sh`. You then can assert the exit code and other things. Since the `config_environment.sh` exports environment variables and we are not able to access them from outside a `run` execution, the function `execute_test_script` wraps our script execution between environment comparison. Doing so allows us capture environment variables that were added/removed during script execution. Reviewed-on: https://gitea.com/gitea/helm-chart/pulls/724 Reviewed-by: pat-s <pat-s@noreply.gitea.com> Co-authored-by: justusbunsi <sk.bunsenbrenner@gmail.com> Co-committed-by: justusbunsi <sk.bunsenbrenner@gmail.com>
This commit is contained in:
1
unittests/bash/bats
Submodule
1
unittests/bash/bats
Submodule
Submodule unittests/bash/bats added at b640ec3cf2
1
unittests/bash/test_helper/bats-assert
Submodule
1
unittests/bash/test_helper/bats-assert
Submodule
Submodule unittests/bash/test_helper/bats-assert added at e2d855bc78
1
unittests/bash/test_helper/bats-mock
Submodule
1
unittests/bash/test_helper/bats-mock
Submodule
Submodule unittests/bash/test_helper/bats-mock added at 93e0128b87
1
unittests/bash/test_helper/bats-support
Submodule
1
unittests/bash/test_helper/bats-support
Submodule
Submodule unittests/bash/test_helper/bats-support added at 9bf10e876d
7
unittests/bash/test_helper/common-setup.bash
Normal file
7
unittests/bash/test_helper/common-setup.bash
Normal file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function common_setup() {
|
||||
load "$TEST_ROOT/test_helper/bats-support/load"
|
||||
load "$TEST_ROOT/test_helper/bats-assert/load"
|
||||
load "$TEST_ROOT/test_helper/bats-mock/stub"
|
||||
}
|
@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
function setup() {
|
||||
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
|
||||
TEST_ROOT="$PROJECT_ROOT/unittests/bash"
|
||||
load "$TEST_ROOT/test_helper/common-setup"
|
||||
common_setup
|
||||
|
||||
export GITEA_APP_INI="$BATS_TEST_TMPDIR/app.ini"
|
||||
export TMP_EXISTING_ENVS_FILE="$BATS_TEST_TMPDIR/existing-envs"
|
||||
export ENV_TO_INI_MOUNT_POINT="$BATS_TEST_TMPDIR/env-to-ini-mounts"
|
||||
|
||||
stub gitea \
|
||||
"generate secret INTERNAL_TOKEN : echo 'mocked-internal-token'" \
|
||||
"generate secret SECRET_KEY : echo 'mocked-secret-key'" \
|
||||
"generate secret JWT_SECRET : echo 'mocked-jwt-secret'" \
|
||||
"generate secret LFS_JWT_SECRET : echo 'mocked-lfs-jwt-secret'"
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
unstub gitea
|
||||
# This condition exists due to https://github.com/jasonkarns/bats-mock/pull/37 being still open
|
||||
if [ $ENV_TO_INI_EXPECTED -eq 1 ]; then
|
||||
unstub environment-to-ini
|
||||
fi
|
||||
}
|
||||
|
||||
# This function exists due to https://github.com/jasonkarns/bats-mock/pull/37 being still open
|
||||
function expect_environment_to_ini_call() {
|
||||
export ENV_TO_INI_EXPECTED=1
|
||||
stub environment-to-ini \
|
||||
"-o $GITEA_APP_INI : echo 'Stubbed environment-to-ini was called!'"
|
||||
}
|
||||
|
||||
function execute_test_script() {
|
||||
currentEnvsBefore=$(env | sort)
|
||||
source $PROJECT_ROOT/scripts/init-containers/config/config_environment.sh
|
||||
local exitCode=$?
|
||||
currentEnvsAfter=$(env | sort)
|
||||
|
||||
# diff as unified +/- output without context before/after
|
||||
diff --unified=0 <(echo "$currentEnvsBefore") <(echo "$currentEnvsAfter")
|
||||
|
||||
exit $exitCode
|
||||
}
|
||||
|
||||
function write_mounted_file() {
|
||||
# either "inlines" or "additionals"
|
||||
scope="${1}"
|
||||
file="${2}"
|
||||
content="${3}"
|
||||
|
||||
mkdir -p "$ENV_TO_INI_MOUNT_POINT/$scope/..data/"
|
||||
echo "${content}" > "$ENV_TO_INI_MOUNT_POINT/$scope/..data/$file"
|
||||
ln -sf "$ENV_TO_INI_MOUNT_POINT/$scope/..data/$file" "$ENV_TO_INI_MOUNT_POINT/$scope/$file"
|
||||
}
|
||||
|
||||
@test "works as expected when nothing is configured" {
|
||||
expect_environment_to_ini_call
|
||||
run $PROJECT_ROOT/scripts/init-containers/config/config_environment.sh
|
||||
|
||||
assert_success
|
||||
assert_line '...Initial secrets generated'
|
||||
assert_line 'Reloading preset envs...'
|
||||
assert_line '=== All configuration sources loaded ==='
|
||||
assert_line 'Stubbed environment-to-ini was called!'
|
||||
}
|
||||
|
||||
@test "exports initial secrets" {
|
||||
expect_environment_to_ini_call
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
assert_line '+GITEA__OAUTH2__JWT_SECRET=mocked-jwt-secret'
|
||||
assert_line '+GITEA__SECURITY__INTERNAL_TOKEN=mocked-internal-token'
|
||||
assert_line '+GITEA__SECURITY__SECRET_KEY=mocked-secret-key'
|
||||
assert_line '+GITEA__SERVER__LFS_JWT_SECRET=mocked-lfs-jwt-secret'
|
||||
}
|
||||
|
||||
@test "does NOT export initial secrets when app.ini already exists" {
|
||||
expect_environment_to_ini_call
|
||||
touch $GITEA_APP_INI
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
assert_line --partial 'An app.ini file already exists.'
|
||||
refute_line '+GITEA__OAUTH2__JWT_SECRET=mocked-jwt-secret'
|
||||
refute_line '+GITEA__SECURITY__INTERNAL_TOKEN=mocked-internal-token'
|
||||
refute_line '+GITEA__SECURITY__SECRET_KEY=mocked-secret-key'
|
||||
refute_line '+GITEA__SERVER__LFS_JWT_SECRET=mocked-lfs-jwt-secret'
|
||||
}
|
||||
|
||||
@test "ensures that preset environment variables take precedence over auto-generated ones" {
|
||||
expect_environment_to_ini_call
|
||||
export GITEA__OAUTH2__JWT_SECRET="pre-defined-jwt-secret"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
refute_line '+GITEA__OAUTH2__JWT_SECRET=mocked-jwt-secret'
|
||||
}
|
||||
|
||||
@test "ensures that preset environment variables take precedence over mounted ones" {
|
||||
expect_environment_to_ini_call
|
||||
export GITEA__OAUTH2__JWT_SECRET="pre-defined-jwt-secret"
|
||||
write_mounted_file "inlines" "oauth2" "$(cat << EOF
|
||||
JWT_SECRET=inline-jwt-secret
|
||||
EOF
|
||||
)"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
refute_line '+GITEA__OAUTH2__JWT_SECRET=mocked-jwt-secret'
|
||||
refute_line '+GITEA__OAUTH2__JWT_SECRET=inline-jwt-secret'
|
||||
}
|
||||
|
||||
@test "ensures that additionals take precedence over inlines" {
|
||||
expect_environment_to_ini_call
|
||||
write_mounted_file "inlines" "oauth2" "$(cat << EOF
|
||||
JWT_SECRET=inline-jwt-secret
|
||||
EOF
|
||||
)"
|
||||
write_mounted_file "additionals" "oauth2" "$(cat << EOF
|
||||
JWT_SECRET=additional-jwt-secret
|
||||
EOF
|
||||
)"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
refute_line '+GITEA__OAUTH2__JWT_SECRET=mocked-jwt-secret'
|
||||
refute_line '+GITEA__OAUTH2__JWT_SECRET=inline-jwt-secret'
|
||||
assert_line '+GITEA__OAUTH2__JWT_SECRET=additional-jwt-secret'
|
||||
}
|
||||
|
||||
@test "ensures that dotted/dashed sections are properly masked" {
|
||||
expect_environment_to_ini_call
|
||||
write_mounted_file "inlines" "repository.pull-request" "$(cat << EOF
|
||||
WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP]
|
||||
EOF
|
||||
)"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
assert_line '+GITEA__REPOSITORY_0X2E_PULL_0X2D_REQUEST__WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP]'
|
||||
}
|
||||
|
||||
###############################################################
|
||||
##### THIS IS A BUG, BUT I WANT IT TO BE COVERED BY TESTS #####
|
||||
###############################################################
|
||||
@test "ensures uppercase section and setting names (🐞)" {
|
||||
expect_environment_to_ini_call
|
||||
export GITEA__oauth2__JwT_Secret="pre-defined-jwt-secret"
|
||||
write_mounted_file "inlines" "repository.pull-request" "$(cat << EOF
|
||||
WORK_IN_progress_PREFIXES=WIP:,[WIP]
|
||||
EOF
|
||||
)"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
assert_line '+GITEA__REPOSITORY_0X2E_PULL_0X2D_REQUEST__WORK_IN_PROGRESS_PREFIXES=WIP:,[WIP]'
|
||||
assert_line '+GITEA__OAUTH2__JWT_SECRET=pre-defined-jwt-secret'
|
||||
}
|
||||
|
||||
@test "treats top-level configuration as section-less" {
|
||||
expect_environment_to_ini_call
|
||||
write_mounted_file "inlines" "_generals_" "$(cat << EOF
|
||||
APP_NAME=Hello top-level configuration
|
||||
RUN_MODE=dev
|
||||
EOF
|
||||
)"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_success
|
||||
assert_line '+GITEA____APP_NAME=Hello top-level configuration'
|
||||
assert_line '+GITEA____RUN_MODE=dev'
|
||||
}
|
||||
|
||||
@test "fails on invalid setting" {
|
||||
write_mounted_file "inlines" "_generals_" "$(cat << EOF
|
||||
some random invalid string
|
||||
EOF
|
||||
)"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_failure
|
||||
}
|
||||
|
||||
@test "treats empty setting name as invalid setting" {
|
||||
write_mounted_file "inlines" "_generals_" "$(cat << EOF
|
||||
=value
|
||||
EOF
|
||||
)"
|
||||
|
||||
run execute_test_script
|
||||
|
||||
assert_failure
|
||||
}
|
Reference in New Issue
Block a user