diff options
| author | Sergio Cazzolato <sergio.cazzolato@canonical.com> | 2023-07-07 12:17:41 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-07 17:17:41 +0200 |
| commit | 7ba95e3a7a22c56e730aa05f0609f37ab3b92036 (patch) | |
| tree | 96b07b84aa76c2ced6557c80c3027d881a09d06d | |
| parent | 4640067371757e901795e664b5f24a7d4b386deb (diff) | |
tests: speed up the prepare phase through a new tool to manage initial snapd env (#12707)
* New tool to manage initial env in spread tests This is used to know in spread tests the initial value for the vars and be able to repeat not needed steps * test fixed * Minor fixes con docs and env var removed * improve tests.env tool
| -rw-r--r-- | spread.yaml | 3 | ||||
| l--------- | tests/bin/tests.env | 1 | ||||
| -rwxr-xr-x | tests/lib/prepare.sh | 60 | ||||
| -rwxr-xr-x | tests/lib/state.sh | 2 | ||||
| -rw-r--r-- | tests/lib/tools/suite/tests.env/task.yaml | 59 | ||||
| -rwxr-xr-x | tests/lib/tools/tests.env | 130 |
6 files changed, 227 insertions, 28 deletions
diff --git a/spread.yaml b/spread.yaml index 0ba63a201e..10fadaca57 100644 --- a/spread.yaml +++ b/spread.yaml @@ -15,6 +15,7 @@ environment: TESTSLIB: $PROJECT_PATH/tests/lib TESTSTOOLS: $PROJECT_PATH/tests/lib/tools TESTSTMP: /var/tmp/snapd-tools + RUNTIME_STATE_PATH: $TESTSTMP/runtime-state # turn debug off so that we don't get errant debug messages while running # tests, and in some cases like on UC20 we have the kernel command line # parameter, snapd.debug=1 turned on to enable early boot debugging before @@ -73,6 +74,8 @@ environment: # Use the installed snapd and reset the systems without removing snapd REUSE_SNAPD: '$(HOST: echo "${SPREAD_REUSE_SNAPD:-0}")' EXPERIMENTAL_FEATURES: '$(HOST: echo "${SPREAD_EXPERIMENTAL_FEATURES:-}")' + # set to 1 when the snapd memory limit has to be removed + SNAPD_NO_MEMORY_LIMIT: '$(HOST: echo "${SPREAD_SNAPD_NO_MEMORY_LIMIT:-}")' SNAPD_PUBLISHED_VERSION: '$(HOST: echo "$SPREAD_SNAPD_PUBLISHED_VERSION")' # Build and use snapd from current branch diff --git a/tests/bin/tests.env b/tests/bin/tests.env new file mode 120000 index 0000000000..fd2854638f --- /dev/null +++ b/tests/bin/tests.env @@ -0,0 +1 @@ +../lib/tools/tests.env \ No newline at end of file diff --git a/tests/lib/prepare.sh b/tests/lib/prepare.sh index fd70674521..42aa27fbc9 100755 --- a/tests/lib/prepare.sh +++ b/tests/lib/prepare.sh @@ -215,6 +215,14 @@ update_core_snap_for_classic_reexec() { } prepare_memory_limit_override() { + # First time it is needed to save the initial env var value + if not tests.env is-set initial SNAPD_NO_MEMORY_LIMIT; then + tests.env set initial SNAPD_NO_MEMORY_LIMIT "$SNAPD_NO_MEMORY_LIMIT" + # Then if the new value is the same than the initial, then no new configuration needed + elif [ "$(tests.env get initial SNAPD_NO_MEMORY_LIMIT)" = "$SNAPD_NO_MEMORY_LIMIT" ]; then + return + fi + # set up memory limits for snapd bu default unless explicit requested not to # or the system is known to be problematic local set_limit=1 @@ -232,7 +240,7 @@ prepare_memory_limit_override() { set_limit=0 ;; *) - if [ -n "${SNAPD_NO_MEMORY_LIMIT:-}" ]; then + if [ "$SNAPD_NO_MEMORY_LIMIT" = 1 ]; then set_limit=0 fi ;; @@ -254,8 +262,7 @@ prepare_memory_limit_override() { # systemd is backwards compatible so the limit is still set. cat <<EOF > /etc/systemd/system/snapd.service.d/memory-max.conf [Service] -# mvo: disabled because of many failures in restore, e.g. in PR#11014 -#MemoryLimit=100M +MemoryLimit=150M EOF fi # the service setting may have changed in the service so we need @@ -264,38 +271,31 @@ EOF systemctl restart snapd } -create_reexec_file(){ - local reexec_file=$1 - cat <<EOF > "$reexec_file" -[Service] -Environment=SNAP_REEXEC=$SNAP_REEXEC -EOF -} - prepare_reexec_override() { local reexec_file=/etc/systemd/system/snapd.service.d/reexec.conf - local updated=false + + # First time it is needed to save the initial env var value + if not tests.env is-set initial SNAP_REEXEC; then + tests.env set initial SNAP_REEXEC "$SNAP_REEXEC" + # Then if the new value is the same than the initial, then no new configuration needed + elif [ "$(tests.env get initial SNAP_REEXEC)" = "$SNAP_REEXEC" ]; then + return + fi # Just update reexec configuration when the SNAP_REEXEC var has been updated # Otherwise it is used the configuration set during project preparation mkdir -p /etc/systemd/system/snapd.service.d - if [ -z "${SNAP_REEXEC:-}" ] && [ -f "$reexec_file" ] ; then + if [ -z "${SNAP_REEXEC:-}" ]; then rm -f "$reexec_file" - updated=true - elif [ -n "${SNAP_REEXEC:-}" ] && [ ! -f "$reexec_file" ]; then - create_reexec_file "$reexec_file" - updated=true - elif [ -n "${SNAP_REEXEC:-}" ] && NOMATCH "Environment=SNAP_REEXEC=$SNAP_REEXEC" < "$reexec_file"; then - create_reexec_file "$reexec_file" - updated=true + else + cat <<EOF > "$reexec_file" +[Service] +Environment=SNAP_REEXEC=$SNAP_REEXEC +EOF fi - if [ "$updated" = true ]; then - # the re-exec setting may have changed in the service so we need - # to ensure snapd is reloaded - systemctl daemon-reload - systemctl restart snapd - fi + systemctl daemon-reload + systemctl restart snapd } prepare_each_classic() { @@ -303,7 +303,9 @@ prepare_each_classic() { echo "/etc/systemd/system/snapd.service.d/local.conf vanished!" exit 1 fi + prepare_reexec_override + prepare_memory_limit_override } prepare_classic() { @@ -360,6 +362,9 @@ prepare_classic() { # Snapshot the state including core. if ! is_snapd_state_saved; then + # Create the file with the initial environment before saving the state + tests.env start initial + # need to be seeded to proceed with snap install # also make sure the captured state is seeded snap wait system seed.loaded @@ -1420,6 +1425,9 @@ prepare_ubuntu_core() { # Snapshot the fresh state (including boot/bootenv) if ! is_snapd_state_saved; then + # Create the file with the initial environment before saving the state + tests.env start initial + # important to remove disabled snaps before calling save_snapd_state # or restore will break remove_disabled_snaps diff --git a/tests/lib/state.sh b/tests/lib/state.sh index 73cdad0b87..6188cb4a60 100755 --- a/tests/lib/state.sh +++ b/tests/lib/state.sh @@ -2,10 +2,8 @@ SNAPD_STATE_PATH="$TESTSTMP/snapd-state" SNAPD_STATE_FILE="$TESTSTMP/snapd-state/snapd-state.tar" -RUNTIME_STATE_PATH="$TESTSTMP/runtime-state" SNAPD_ACTIVE_UNITS="$RUNTIME_STATE_PATH/snapd-active-units" - delete_snapd_state() { rm -rf "$SNAPD_STATE_PATH" } diff --git a/tests/lib/tools/suite/tests.env/task.yaml b/tests/lib/tools/suite/tests.env/task.yaml new file mode 100644 index 0000000000..dcfc6be923 --- /dev/null +++ b/tests/lib/tools/suite/tests.env/task.yaml @@ -0,0 +1,59 @@ +summary: tests for tests.env + +restore: | + rm -f "$RUNTIME_STATE_PATH"/test1.env "$RUNTIME_STATE_PATH"/test2.env + +execute: | + # Both -h and --help are also recognized. + tests.env --help | MATCH "usage: tests.env start <ENV_NAME>" + tests.env -h | MATCH "usage: tests.env start <ENV_NAME>" + + # check start env file + tests.env start test1 + test -f "$RUNTIME_STATE_PATH"/test1.env + + # check commands is-set and set + not tests.env is-set test1 var1 + tests.env set test1 var1 val1 + tests.env is-set test1 var1 + tests.env set test1 var3 + tests.env set test1 var4 "" + + # check command get + test "$(tests.env get test1 var1)" = "val1" + test "$(tests.env get test1 var3)" = "" + test "$(tests.env get test1 var4)" = "" + + # check set another value + not tests.env is-set test1 var2 + tests.env set test1 var2 val2 + tests.env is-set test1 var2 + test "$(tests.env get test1 var2)" = "val2" + test "$(tests.env get test1 var1)" = "val1" + + # check update the value + tests.env set test1 var1 val3 + test "$(tests.env get test1 var1)" = "val3" + + # create another env + tests.env start test2 + tests.env set test2 var1 val1 + test "$(tests.env get test1 var1)" = "val3" + test "$(tests.env get test2 var1)" = "val1" + + # check errors + tests.env test 2>&1 | MATCH "tests.env: no such command: test" + + tests.env start 2>&1 | MATCH "tests.env: name for the env file is required" + + tests.env is-set 2>&1 | MATCH "tests.env: name for the env file is required" + tests.env is-set test1 2>&1 | MATCH "tests.env: variable to check in env file is required" + tests.env is-set test10 var1 2>&1 | MATCH "tests.env: env file $RUNTIME_STATE_PATH/test10.env does not exist" + + tests.env get 2>&1 | MATCH "tests.env: name for the env file is required" + tests.env get test1 2>&1 | MATCH "tests.env: variable to check in env file is required" + tests.env get test10 var1 2>&1 | MATCH "tests.env: env file $RUNTIME_STATE_PATH/test10.env does not exist" + + tests.env set 2>&1 | MATCH "tests.env: name for the env file is required" + tests.env set test1 2>&1 | MATCH "tests.env: variable to set in env file is required" + tests.env set test10 var1 val1 2>&1 | MATCH "tests.env: env file $RUNTIME_STATE_PATH/test10.env does not exist" diff --git a/tests/lib/tools/tests.env b/tests/lib/tools/tests.env new file mode 100755 index 0000000000..a302a254e3 --- /dev/null +++ b/tests/lib/tools/tests.env @@ -0,0 +1,130 @@ +#!/bin/bash + +show_help() { + echo "usage: tests.env start <ENV_NAME>" + echo " tests.env is-set <ENV_NAME> <VAR>" + echo " tests.env get <ENV_NAME> <VAR>" + echo " tests.env set <ENV_NAME> <VAR> <VAL>" + echo "" + echo "The tool is used to create an environment file" + echo " which can be shared across different tests and suites" +} + +start() { + local NAME=$1 + if [ -z "$NAME" ]; then + echo "tests.env: name for the env file is required" + exit 1 + fi + + if [ -f "$RUNTIME_STATE_PATH/$NAME.env" ]; then + echo "tests.env: env file $RUNTIME_STATE_PATH/$NAME.env already exists, deleting..." + rm -f "$RUNTIME_STATE_PATH/$NAME.env" + fi + mkdir -p "$RUNTIME_STATE_PATH" + touch "$RUNTIME_STATE_PATH/$NAME.env" +} + +is_set() { + local NAME=$1 + local VAR=$2 + + if [ -z "$NAME" ]; then + echo "tests.env: name for the env file is required" + exit 1 + fi + if [ -z "$VAR" ]; then + echo "tests.env: variable to check in env file is required" + exit 1 + fi + + if [ ! -f "$RUNTIME_STATE_PATH/$NAME.env" ]; then + echo "tests.env: env file $RUNTIME_STATE_PATH/$NAME.env does not exist" + exit 1 + fi + + grep -Eq "^${VAR}=" "$RUNTIME_STATE_PATH/$NAME.env" +} + +get() { + local NAME=$1 + local VAR=$2 + + if [ -z "$NAME" ]; then + echo "tests.env: name for the env file is required" + exit 1 + fi + if [ -z "$VAR" ]; then + echo "tests.env: variable to check in env file is required" + exit 1 + fi + + if [ ! -f "$RUNTIME_STATE_PATH/$NAME.env" ]; then + echo "tests.env: env file $RUNTIME_STATE_PATH/$NAME.env does not exist" + exit 1 + fi + + if is_set "$NAME" "$VAR"; then + grep -E "^${VAR}=" "$RUNTIME_STATE_PATH/$NAME.env" | cut -d "=" -f2- + fi +} + +set() { + local NAME=$1 + local VAR=$2 + local VAL=$3 + + if [ -z "$NAME" ]; then + echo "tests.env: name for the env file is required" + exit 1 + fi + if [ -z "$VAR" ]; then + echo "tests.env: variable to set in env file is required" + exit 1 + fi + + if [ ! -f "$RUNTIME_STATE_PATH/$NAME.env" ]; then + echo "tests.env: env file $RUNTIME_STATE_PATH/$NAME.env does not exist" + exit 1 + fi + + if is_set "$NAME" "$VAR"; then + sed -i -E "s/^${VAR}=.*/${VAR}=${VAL}/" "$RUNTIME_STATE_PATH/$NAME.env" + else + echo "${VAR}=${VAL}" >> "$RUNTIME_STATE_PATH/$NAME.env" + fi + +} + +main() { + if [ $# -eq 0 ]; then + show_help + exit 0 + fi + + local subcommand="$1" + local action= + while [ $# -gt 0 ]; do + case "$subcommand" in + -h|--help) + show_help + exit 0 + ;; + *) + action=$(echo "$subcommand" | tr '-' '_') + shift + break + ;; + esac + done + + if [ -z "$(declare -f "$action")" ]; then + echo "tests.env: no such command: $subcommand" + show_help + exit 1 + fi + + "$action" "$@" +} + +main "$@" |
