feat(mod_env): introduce mod environment file

- Added `.mod_env` file to store environment configurations for mods.
- The file includes settings for `CURRENT_MOD`, `DEPENDENCIES`, and `CLIENT_NB`.
- Modifications across various files to incorporate and reference values from `.mod_env`.
- Docker-related scripts updated to utilize variables from `.mod_env`.
This commit is contained in:
Yves-Marie Haussonne 2024-10-10 01:19:06 +02:00
parent ae9daa881b
commit b77733ed70
9 changed files with 96 additions and 55 deletions

2
.envrc Normal file
View File

@ -0,0 +1,2 @@
dotenv_if_exists .mod_env

View File

@ -7,8 +7,8 @@ default:
- apk --no-cache add bash - apk --no-cache add bash
stages: stages:
- test
- build - build
- test
- release - release
variables: variables:

4
.mod_env Normal file
View File

@ -0,0 +1,4 @@
CURRENT_MOD=test_harness
DEPENDENCIES=[{ "url":"https://github.com/minetest/minetest_game/archive/refs/heads/master.tar.gz", "path":"/usr/local/share/minetest/games/minetest", "strip":1 }]
MINETEST_ADD_CONF=
CLIENT_NB=1

4
.util/.mod_env.tmpl Normal file
View File

@ -0,0 +1,4 @@
CURRENT_MOD=test_harness
CLIENT_NB=1
DEPENDENCIES=[{ "url":"https://github.com/minetest/minetest_game/archive/refs/heads/master.tar.gz", "path":"/usr/local/share/minetest/games/minetest", "strip":1 }, { "url":"https://forge.apps.education.fr/iri/minetest/docker_test_harness/-/archive/main/docker_test_harness-main.tar.gz", "path":"/usr/local/share/minetest/games/minetest/mods/test_harness", "strip":1 }]
MINETEST_ADD_CONF=

View File

@ -1,7 +1,7 @@
FROM curlimages/curl:latest as dl_base #
# list of mods and game to download ARG DEPENDENCIES
RUN mkdir -p minetest_game && curl -s -L https://github.com/minetest/minetest_game/archive/refs/heads/master.tar.gz | tar zxvf - -C minetest_game --strip-components=1 ARG MINETEST_ADD_CONF=""
FROM ghcr.io/minetest/minetest:latest as builder FROM ghcr.io/minetest/minetest:latest as builder
@ -9,17 +9,24 @@ ENV STOP_SERVER=true
ENV FAILFAST=false ENV FAILFAST=false
ENV MINETEST_GAME_PATH=/usr/local/share/minetest/games ENV MINETEST_GAME_PATH=/usr/local/share/minetest/games
ENV SHOW_DEBUG=false ENV SHOW_DEBUG=false
ENV CURRENT_MOD="test_harness"
ENV ADDITIONAL_MODS=""
USER root USER root
RUN mkdir -p /usr/local/share/minetest/games && \ RUN mkdir -p /usr/local/share/minetest/games && \
apk add --no-cache bash apk add --no-cache bash curl jq
# WORKDIR /config/.minetest/games/devtest/mods # WORKDIR /config/.minetest/games/devtest/mods
RUN <<EOF
# Copy from the dl base the game and mods to their correct path in the game or mod folders while read dep; do
COPY --from=dl_base /home/curl_user/minetest_game /usr/local/share/minetest/games/minetest url=$(echo "$dep" | jq -r ".url")
dep_path=$(echo "$dep" | jq -r ".path")
strip=$(echo "$dep" | jq -r ".strip // 1")
echo "Download $url to $dep_path with strip=$strip"
mkdir -p "$dep_path" && curl -s -L "$url" | tar zxf - -C "$dep_path" --strip-components="$strip"
done < <(echo "$DEPENDENCIES" | jq -c '.[]')
EOF
COPY <<"EOF" /usr/local/sbin/run_minetest COPY <<"EOF" /usr/local/sbin/run_minetest
#!/usr/bin/env bash #!/usr/bin/env bash
@ -39,6 +46,7 @@ function clean_up {
rm -f /etc/minetest/minetest.conf rm -f /etc/minetest/minetest.conf
cat /etc/minetest/minetest.conf.base - <<-EOT > /etc/minetest/minetest.conf cat /etc/minetest/minetest.conf.base - <<-EOT > /etc/minetest/minetest.conf
test_harness_mods=${CURRENT_MOD}${ADDITIONAL_MODS}
test_harness_stop_server=${STOP_SERVER} test_harness_stop_server=${STOP_SERVER}
test_harness_failfast=${FAILFAST} test_harness_failfast=${FAILFAST}
EOT EOT
@ -66,7 +74,6 @@ EOF
# Customize the test_harness_mods value to list the mods to test. Empty value means all, including the test harness itself # Customize the test_harness_mods value to list the mods to test. Empty value means all, including the test harness itself
COPY <<-EOF /etc/minetest/minetest.conf.base COPY <<-EOF /etc/minetest/minetest.conf.base
test_harness_mods=test_harness
test_harness_run_tests=true test_harness_run_tests=true
max_forceloaded_blocks=9999 max_forceloaded_blocks=9999
name=admin name=admin
@ -79,6 +86,7 @@ COPY <<-EOF /etc/minetest/minetest.conf.base
water_level=-2 water_level=-2
mgflat_ground_level=-1 mgflat_ground_level=-1
mg_flags=nocaves,nodungeons,nolight,nodecorations,nobiomes,noores mg_flags=nocaves,nodungeons,nolight,nodecorations,nobiomes,noores
${MINETEST_ADD_CONF}
EOF EOF
RUN chown -R minetest:minetest /var/lib/minetest/.minetest /usr/local/sbin/run_minetest && \ RUN chown -R minetest:minetest /var/lib/minetest/.minetest /usr/local/sbin/run_minetest && \

View File

@ -4,23 +4,17 @@ services:
restart: "no" restart: "no"
build: build:
dockerfile: Dockerfile dockerfile: Dockerfile
args:
DEPENDENCIES: "${DEPENDENCIES}"
MINETEST_ADD_CONF: "${MINETEST_ADD_CONF:-}"
ports: ports:
- "30000:30000/udp" - "30000:30000/udp"
volumes: volumes:
- "$PWD:/usr/local/share/minetest/games/minetest/mods/test_harness" - "$PWD:/usr/local/share/minetest/games/minetest/mods/${CURRENT_MOD}"
environment: environment:
SHOW_DEBUG: ${SHOW_DEBUG} SHOW_DEBUG: ${SHOW_DEBUG}
RUN_TESTS: ${RUN_TESTS} RUN_TESTS: ${RUN_TESTS}
STOP_SERVER: ${STOP_SERVER} STOP_SERVER: ${STOP_SERVER}
FAILFAST: ${FAILFAST} FAILFAST: ${FAILFAST}
client1: CURRENT_MOD: "${CURRENT_MOD}"
image: ${CLIENT_IMAGE} ADDITIONAL_MODS: "${ADDITIONAL_MODS:-}"
restart: on-failure:10
depends_on:
- "server"
environment:
SERVER: server
PORT: 30000
PLAYERNAME: player1
RANDOM_INPUT: 0
PASSWORD: test

View File

@ -7,25 +7,32 @@ script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
usage() { usage() {
cat <<EOF cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-D] [-f/--failfast] [-k/--keep-server] [-i/--image docker_image] [-p/--port port_server] Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-D] [-f/--failfast] [-k/--keep-server] [-p/--port port_server] [--dependencies mod_dependencies] [-c/--clients nb_of_client]
Start tests. Start tests.
Available options: Available options:
-h, --help Print this help and exit -h, --help Print this help and exit
-d, --docker-cmd The container engine (docker or podman)
--podman Use podman as container engine
--docker Use docker as container engine
-D, --show-debug Display debug.txt content on exit -D, --show-debug Display debug.txt content on exit
-f, --failfast Failfast tests -f, --failfast Failfast tests
-k, --keep-server Keep the server running -k, --keep-server Keep the server running
-i, --image Pass the image to use for the tests
-p, --port Server port -p, --port Server port
-c, --clients Number of client, default to \$CLIENT_NB
--dependencies mod dependencies
EOF EOF
exit exit
} }
cleanup() { cleanup() {
trap - SIGINT SIGTERM ERR EXIT trap - SIGINT SIGTERM ERR EXIT
eval $docker_cmd compose -f "${script_dir}/docker-compose.yaml" down eval $docker_cmd compose -f "${docker_compose_file}" down
if [-f "${docker_compose_file:-}" ]; then
\rm "${docker_compose_file}"
fi
} }
setup_colors() { setup_colors() {
@ -64,18 +71,18 @@ isuint() { [[ $1 == +([0-9]) ]] ;}
docker_cmd= docker_cmd=
docker_build_cmd="build" docker_build_cmd="build"
docker_image=
client_image= client_image=
client_nb=0 client_nb=${CLIENT_NB:-1}
failfast="false" failfast="false"
stop_server="true" stop_server="true"
server_port="30000" server_port="30000"
show_debug="false" show_debug="false"
run_tests="all" run_tests="all"
dependencies="${DEPENDENCIES:-}"
parse_params() { parse_params() {
# init switch flags # init switch flags
args=$(getopt -a -o Dfhki:c:p:d:t: --long show-debug,failfast,keep-server,help,podman,docker,image:,client:,client-image:,port:,docker-cmd:,tests: -- "$@") args=$(getopt -a -o Dfhkc:p:d:t: --long show-debug,failfast,keep-server,help,podman,docker,clients:,client-image:,port:,docker-cmd:,tests:,dependencies: -- "$@")
if [[ $? -gt 0 ]]; then if [[ $? -gt 0 ]]; then
usage usage
fi fi
@ -119,18 +126,18 @@ parse_params() {
run_tests=$2 run_tests=$2
shift 2 shift 2
;; ;;
-i | --image)
docker_image=$2
shift 2
;;
--client-image) --client-image)
client_image=$2 client_image=$2
shift 2 shift 2
;; ;;
-c | --client) -c | --clients)
client_nb=$2 client_nb=$2
shift 2 shift 2
;; ;;
--dependencies)
dependencies=$2
shift 2
;;
# -- means the end of the arguments; drop this, and break out of the while loop # -- means the end of the arguments; drop this, and break out of the while loop
--) --)
shift shift
@ -187,17 +194,45 @@ vol=(
[ -d minetest_game ] && vol+=( [ -d minetest_game ] && vol+=(
-v "$PWD/minetest_game":/var/lib/minetest/.minetest/games/minetest_game -v "$PWD/minetest_game":/var/lib/minetest/.minetest/games/minetest_game
) )
echo "docker_image: |$docker_image|"
export SHOW_DEBUG=${show_debug:-false} export SHOW_DEBUG=${show_debug:-false}
export RUN_TESTS=${run_tests} export RUN_TESTS=${run_tests}
export STOP_SERVER="${stop_server:-true}" export STOP_SERVER="${stop_server:-true}"
export FAILFAST="${failfast:-false}" export FAILFAST="${failfast:-false}"
export CLIENT_IMAGE="${client_image:-registry.apps.education.fr/iri/minetest/docker-test-harness/client:latest}" export DEPENDENCIES="${dependencies}"
export CLIENT_IMAGE="${client_image:-registry.apps.education.fr/iri/minetest/docker_test_harness/client:latest}"
if [ -z "$($docker_cmd images -q $CLIENT_IMAGE 2> /dev/null)" ]; then
die "CLIENT IMAGE $CLIENT_IMAGE does not exists"
fi
export ENV_FILE=""
if [ -f "$PWD/.mod_env" ]; then
ENV_FILE="--env-file \"$PWD/.mod_env\""
fi
eval $docker_cmd compose -f "${script_dir}/docker-compose.yaml" down docker_compose_file=`mktemp --suffix=.yaml docker-composeXXXXXX`
eval $docker_cmd compose -f "${script_dir}/docker-compose.yaml" pull
eval $docker_cmd compose -f "${script_dir}/docker-compose.yaml" build --pull cat "${script_dir}/docker-compose.yaml" > $docker_compose_file
eval $docker_cmd compose -f "${script_dir}/docker-compose.yaml" up --force-recreate --exit-code-from server --abort-on-container-exit for (( clienti=1; clienti<=$client_nb; clienti++ )); do
cat <<EOF >> $docker_compose_file
client${clienti}:
image: \${CLIENT_IMAGE}
restart: on-failure:10
depends_on:
- "server"
environment:
SERVER: server
PORT: 30000
PLAYERNAME: player${clienti}
RANDOM_INPUT: 0
PASSWORD: test
EOF
done
eval $docker_cmd compose $ENV_FILE -f "${$docker_compose_file}" down
eval $docker_cmd compose $ENV_FILE -f "${$docker_compose_file}" pull
eval $docker_cmd compose $ENV_FILE -f "${$docker_compose_file}" build --pull
eval $docker_cmd compose $ENV_FILE -f "${$docker_compose_file}" up --force-recreate --exit-code-from server --abort-on-container-exit
exit_code=$? exit_code=$?
exit $exit_code exit $exit_code

View File

@ -21,30 +21,24 @@ The tests are run using Docker or Podman. Therefor you'll need to have either on
This mod's goal is to provide a test framework for implementing tests for minetest mods. This mod's goal is to provide a test framework for implementing tests for minetest mods.
1. Declare `test_harness` as an optional dependencies for your mod 1. Declare `test_harness` as an optional dependencies for your mod
2. Clone or download the `docker-test-harness` mod. 2. copy the `.util` folder in your project
3. Place the `test_harness` directory into the `mods` folder of your Minetest world. 3. copy the `.util/.mod_env.tmpl` to `.mod_env` at the root of your folder.
4. copy the `.util` folder in your project 4. adapt its content. Do not remove the test_harness dependency definition.
5. Customize the `.util/Dockerfile` to include the mods and game your project depends on (download and copy) 5. if necessary, customize the `.util/Dockerfile` to adapt the `/etc/minetest/minetest.conf.base` file to list the mods you want to test (`test_harness_mods`), and to adjust the server configuration to your project test settings.
6. Customize the `.util/Dockerfile` to adapt the `/etc/minetest/minetest.conf.base` file to list the mods you want to test (`test_harness_mods`), and to adjust the server configuration to your project test settings. 6. In your source files (in the `init.lua` for example) add the following lines (or equivalent)
7. Do not forget the following setting in `/etc/minetest/minetest.conf.base` to enable automatic test execution:/etc/minetest/minetest.conf.base
```ini
test_harness_run_tests = true
```
8. In your source files (in the `init.lua` for example) add the following lines (or equivalent)
```lua ```lua
if minetest.settings:get_bool("test_harness_run_tests", false) then if minetest.settings:get_bool("test_harness_run_tests", false) then
dofile(minetest.get_modpath("my_mod").. "/test/init.lua") dofile(minetest.get_modpath("my_mod").. "/test/init.lua")
end end
``` ```
9. In your test file(s), get an instance of the method allowing the registration of your tests: 7. In your test file(s), get an instance of the method allowing the registration of your tests:
```lua ```lua
local register_test = test_harness.get_test_registrator("my_mod", my_mod.version_string) local register_test = test_harness.get_test_registrator("my_mod", my_mod.version_string)
``` ```
10. Register the test by calling `register_test` 8. Register the test by calling `register_test`
11. Adapt the `.util/docker-compose.yaml` to declare all the client intances with their players needed by your tests 9. Run the test by lauching the `run_tests.sh` script. For example with Podman
12. Run the test by lauching the `run_tests.sh` script. For example with Podman
```shell ```shell
$ .util/run_tests.sh --podman $ .util/run_tests.sh --podman -c 1
``` ```
See the available options with `.util/run_tests.sh --help` See the available options with `.util/run_tests.sh --help`

View File

@ -1,4 +1,4 @@
ARG OPENGL_BASE_IMAGE="registry.apps.education.fr/iri/minetest/docker-test-harness/opengl:latest" ARG OPENGL_BASE_IMAGE="registry.apps.education.fr/iri/minetest/docker_test_harness/opengl:latest"
FROM alpine:latest AS compile FROM alpine:latest AS compile
ARG MINETEST_VERSION=5.9.1 ARG MINETEST_VERSION=5.9.1