From 74f5144b248a6668f38bc8a0ea8f0999498cc799 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Fri, 4 Apr 2025 18:47:12 -0300 Subject: [PATCH 01/25] feat: Add func to detect nested values and drop it Signed-off-by: Lincoln Wallace --- env-exporter.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/env-exporter.sh b/env-exporter.sh index 98eb8e7..024ab6f 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -18,11 +18,27 @@ debug_hash_table() { done } +is_nested_json() { + local json_input="$1" + local nested_json_pattern='^\{.*\{.*\}.*\}.*$' + + if [[ $json_input =~ $nested_json_pattern ]]; then + return 0 + else + return 1 + fi +} + json_to_hash_table() { local -n hash_table=$1 shift local json_input="$@" + if is_nested_json "$json_input"; then + err "Nested snap options keys aren't supported: $json_input" + return 1 + fi + json_input=$(echo "$json_input" | sed 's/[{}]//g' | tr -d '[:space:]') IFS=',' read -ra kv_pairs <<<"$json_input" From 3a7777d828f4afa5604e1bbbdfc3bea14ca7b8c2 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Mon, 7 Apr 2025 15:34:36 -0300 Subject: [PATCH 02/25] feat: add context to error Signed-off-by: Lincoln Wallace --- env-exporter.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/env-exporter.sh b/env-exporter.sh index 024ab6f..89f8e27 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -29,13 +29,19 @@ is_nested_json() { fi } +catch_nested_json() { + local json_input="$1" + echo "$json_input" | grep -oE '"[^"]*"\s*:\s*\{[^}]*\}' +} + json_to_hash_table() { local -n hash_table=$1 shift local json_input="$@" if is_nested_json "$json_input"; then - err "Nested snap options keys aren't supported: $json_input" + local nested=$(catch_nested_json $json_input) + err "Nested snap options keys aren't supported: $nested" return 1 fi From e99521d05c09a4355167fc77ce49d16e5ab7bb3d Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Mon, 7 Apr 2025 16:20:08 -0300 Subject: [PATCH 03/25] fix: use right RegEx Signed-off-by: Lincoln Wallace --- env-exporter.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-exporter.sh b/env-exporter.sh index 89f8e27..1062b6b 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -31,7 +31,7 @@ is_nested_json() { catch_nested_json() { local json_input="$1" - echo "$json_input" | grep -oE '"[^"]*"\s*:\s*\{[^}]*\}' + echo "$json_input" | grep -oE '^\{.*\{.*\}.*\}.*$' } json_to_hash_table() { From df71dd209068fe28efa92756360472bf551dd11c Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Mon, 7 Apr 2025 19:47:12 -0300 Subject: [PATCH 04/25] debug: add trace Signed-off-by: Lincoln Wallace --- env-exporter.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/env-exporter.sh b/env-exporter.sh index 1062b6b..0fb7287 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -x + debug() { [ "$DEBUG" != "true" ] && return echo -e "[DEBUG] $1" From 9b74b4a67894b13e6787db83903e484edb7febb3 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Mon, 7 Apr 2025 20:25:19 -0300 Subject: [PATCH 05/25] refact: add missing quotations Signed-off-by: Lincoln Wallace --- env-exporter.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-exporter.sh b/env-exporter.sh index 0fb7287..24cf2ff 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -42,7 +42,7 @@ json_to_hash_table() { local json_input="$@" if is_nested_json "$json_input"; then - local nested=$(catch_nested_json $json_input) + local nested=$(catch_nested_json "$json_input") err "Nested snap options keys aren't supported: $nested" return 1 fi From 6e78601b800f1f7eab3ec835074cff6ce65acb7a Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Mon, 7 Apr 2025 20:56:38 -0300 Subject: [PATCH 06/25] feat: revert prev regex Signed-off-by: Lincoln Wallace --- env-exporter.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-exporter.sh b/env-exporter.sh index 24cf2ff..4ff2907 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -33,7 +33,7 @@ is_nested_json() { catch_nested_json() { local json_input="$1" - echo "$json_input" | grep -oE '^\{.*\{.*\}.*\}.*$' + echo "$json_input" | grep -oE '"[^"]*"\s*:\s*\{[^}]*\}' } json_to_hash_table() { From 06cf2cdf59a8851bae8b02ea7b3edceeb2f0064b Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Mon, 7 Apr 2025 20:58:21 -0300 Subject: [PATCH 07/25] feat: exit 1 on error Signed-off-by: Lincoln Wallace --- env-exporter.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env-exporter.sh b/env-exporter.sh index 4ff2907..377b870 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -44,7 +44,7 @@ json_to_hash_table() { if is_nested_json "$json_input"; then local nested=$(catch_nested_json "$json_input") err "Nested snap options keys aren't supported: $nested" - return 1 + exit 1 fi json_input=$(echo "$json_input" | sed 's/[{}]//g' | tr -d '[:space:]') From 70571dd7c4bb879a02ee67fee3d194eba51c1e22 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Mon, 7 Apr 2025 21:04:16 -0300 Subject: [PATCH 08/25] feat!: drop trace Signed-off-by: Lincoln Wallace --- env-exporter.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/env-exporter.sh b/env-exporter.sh index 377b870..a299a31 100755 --- a/env-exporter.sh +++ b/env-exporter.sh @@ -1,7 +1,5 @@ #!/bin/bash -set -x - debug() { [ "$DEBUG" != "true" ] && return echo -e "[DEBUG] $1" From deff3d56807484f8768cd66d4c222416439cb4e6 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 09:37:58 -0300 Subject: [PATCH 09/25] feat: change app names to app1 and app2 Signed-off-by: Lincoln Wallace --- tests/test-snappyenv | 70 ++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/tests/test-snappyenv b/tests/test-snappyenv index b36c586..2393887 100755 --- a/tests/test-snappyenv +++ b/tests/test-snappyenv @@ -16,9 +16,9 @@ echo "SNAP NAME: ${SNAP}" pushd "$PROJECT_ROOT" || exit 1 # 'sudo -u "$RUN_AS"' prevents a permission denied error when using yq as snap. -sudo -u "$SUDO_USER" yq '.apps.app-rust-2 = { +sudo -u "$SUDO_USER" yq '.apps.app2 = { "environment": { - "env_alias": "app-rust-2" + "env_alias": "app2" }, "command-chain": [ "bin/env-exporter" @@ -41,26 +41,26 @@ echo "Load global envfile" snap set "${SNAP}" envfile="$SNAP_COMMON"/global.env echo "[TEST] - Check if the global envfile is loaded the app using Rust snappy-env programs" -check_env_exist "${SNAP}.app-rust" "HELLO_WORLD" || fail -check_env_value "${SNAP}.app-rust" "HELLO_WORLD" "Hello World" || fail +check_env_exist "${SNAP}.app1" "HELLO_WORLD" || fail +check_env_value "${SNAP}.app1" "HELLO_WORLD" "Hello World" || fail -check_env_exist "${SNAP}.app-rust-2" "HELLO_WORLD" || fail -check_env_value "${SNAP}.app-rust-2" "HELLO_WORLD" "Hello World" || fail +check_env_exist "${SNAP}.app2" "HELLO_WORLD" || fail +check_env_value "${SNAP}.app2" "HELLO_WORLD" "Hello World" || fail echo -e "\n[envtester] Creating app-specific envfile" -echo 'SCOPED=RustVersion' >>"$SNAP_COMMON"/rust.env -echo 'SCOPED=Rust2Version' >>"$SNAP_COMMON"/rust-2.env +echo 'SCOPED=RustVersion' >>"$SNAP_COMMON"/envs.env +echo 'SCOPED=Rust2Version' >>"$SNAP_COMMON"/envs2.env echo "Load app-specific envfile" -snap set "${SNAP}" apps.app-rust.envfile="$SNAP_COMMON"/rust.env -snap set "${SNAP}" apps.app-rust-2.envfile="$SNAP_COMMON"/rust-2.env +snap set "${SNAP}" apps.app1.envfile="$SNAP_COMMON"/envs.env +snap set "${SNAP}" apps.app2.envfile="$SNAP_COMMON"/envs2.env echo "[TEST] - Check if the app-specific envfile is loaded for the apps" -check_env_exist "${SNAP}.app-rust" "SCOPED" || fail -check_env_value "${SNAP}.app-rust" "SCOPED" "RustVersion" || fail +check_env_exist "${SNAP}.app1" "SCOPED" || fail +check_env_value "${SNAP}.app1" "SCOPED" "RustVersion" || fail -check_env_exist "${SNAP}.app-rust-2" "SCOPED" || fail -check_env_value "${SNAP}.app-rust-2" "SCOPED" "Rust2Version" || fail +check_env_exist "${SNAP}.app2" "SCOPED" || fail +check_env_value "${SNAP}.app2" "SCOPED" "Rust2Version" || fail echo -e "\n[envtester] Setting global env variable" @@ -68,44 +68,44 @@ echo "Set env vars: Global" snap set "${SNAP}" env.global="World" echo "[TEST] - Check if the global env var is set for all apps" -check_env_exist "${SNAP}.app-rust" "GLOBAL" || fail -check_env_value "${SNAP}.app-rust" "GLOBAL" "World" || fail +check_env_exist "${SNAP}.app1" "GLOBAL" || fail +check_env_value "${SNAP}.app1" "GLOBAL" "World" || fail -check_env_exist "${SNAP}.app-rust-2" "GLOBAL" || fail -check_env_value "${SNAP}.app-rust-2" "GLOBAL" "World" || fail +check_env_exist "${SNAP}.app2" "GLOBAL" || fail +check_env_value "${SNAP}.app2" "GLOBAL" "World" || fail echo -e "\n[envtester] Setting app-specific env variable" echo "Set env vars: specific to each app" -snap set "${SNAP}" apps.app-rust.env.hello="Hello" -snap set "${SNAP}" apps.app-rust-2.env.specific="City" +snap set "${SNAP}" apps.app1.env.hello="Hello" +snap set "${SNAP}" apps.app2.env.specific="City" -echo "[TEST] - Check if the app-specific env var IS SET for the app 'app-rust'" -check_env_exist "${SNAP}.app-rust" "HELLO" || fail -check_env_value "${SNAP}.app-rust" "HELLO" "Hello" || fail +echo "[TEST] - Check if the app-specific env var IS SET for the app 'app1'" +check_env_exist "${SNAP}.app1" "HELLO" || fail +check_env_value "${SNAP}.app1" "HELLO" "Hello" || fail -echo -e "\n[TEST] - Check if the app-specific env var IS NOT SET for the app 'app-rust-2'" -check_env_not_exist "${SNAP}.app-rust-2" "HELLO" || fail +echo -e "\n[TEST] - Check if the app-specific env var IS NOT SET for the app 'app2'" +check_env_not_exist "${SNAP}.app2" "HELLO" || fail -echo -e "\n[TEST] - Check if the app-specific env var IS SET for the app 'app-rust-2'" -check_env_exist "${SNAP}.app-rust-2" "SPECIFIC" || fail -check_env_value "${SNAP}.app-rust-2" "SPECIFIC" "City" || fail +echo -e "\n[TEST] - Check if the app-specific env var IS SET for the app 'app2'" +check_env_exist "${SNAP}.app2" "SPECIFIC" || fail +check_env_value "${SNAP}.app2" "SPECIFIC" "City" || fail -echo -e "\n[TEST] - Check if the app-specific env var IS NOT SET for the app 'app-rust'" -check_env_not_exist "${SNAP}.app-rust" "SPECIFIC" || fail +echo -e "\n[TEST] - Check if the app-specific env var IS NOT SET for the app 'app1'" +check_env_not_exist "${SNAP}.app1" "SPECIFIC" || fail echo -e "\n[envtester] Testing order of env vars" echo 'ORDER="From envfile"' >>"$SNAP_COMMON"/local.env -snap set "${SNAP}" apps.app-rust.env.order="from snap option" -snap set "${SNAP}" apps.app-rust.envfile="$SNAP_COMMON"/local.env +snap set "${SNAP}" apps.app1.env.order="from snap option" +snap set "${SNAP}" apps.app1.envfile="$SNAP_COMMON"/local.env echo "[TEST] - Check if local overrides global" -check_env_exist "${SNAP}.app-rust" "ORDER" || fail -check_env_value "${SNAP}.app-rust" "ORDER" "from snap option" || fail +check_env_exist "${SNAP}.app1" "ORDER" || fail +check_env_value "${SNAP}.app1" "ORDER" "from snap option" || fail echo -e "\n[envtester] Testing options syntax" snap set "${SNAP}" env.word.dot="wrong" echo "[TEST] - Check if the key with dot was ignored" -check_syntax "${SNAP}.app-rust" "wrong" || fail +check_syntax "${SNAP}.app1" "wrong" || fail snap unset "${SNAP}" env.word.dot clean From 891013cc83c459c9cedb6ac1bee74f073dc4e98c Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:08:34 -0300 Subject: [PATCH 10/25] feat: patch snapcraft.yaml with app1 and app2 Signed-off-by: Lincoln Wallace --- tests/initialize | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/tests/initialize b/tests/initialize index e2cceef..b333cb3 100755 --- a/tests/initialize +++ b/tests/initialize @@ -73,15 +73,36 @@ fail() { inject_test_app() { sudo snap install yq - sudo -u "$SUDO_USER" yq '.apps.app-rust-2 = { + + if [[ -z "${impl_map[$1]}" ]]; then + echo "Error: unknown implementation '$1'" + help + fi + + local exporter="${impl_map[$1]}" + + # Create app1 + sudo -u "$SUDO_USER" yq '.apps.app1 = { + "environment": { + "env_alias": "app1" + }, + "command-chain": [ + "bin/$exporter" + ], + "command": "bin/env.sh" + }' -i "snap/snapcraft.yaml" + + # Create app2 + sudo -u "$SUDO_USER" yq '.apps.app2 = { "environment": { - "env_alias": "app-rust-2" + "env_alias": "app2" }, "command-chain": [ - "bin/env-exporter" + "bin/$exporter" ], "command": "bin/env.sh" }' -i "snap/snapcraft.yaml" + } init_tests() { From f9ec1f378f60dbe5ce25c68fd11f1e42a2045efc Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:09:33 -0300 Subject: [PATCH 11/25] feat: add -i/--impl parameter to set rust or bash implementation Signed-off-by: Lincoln Wallace --- tests/initialize | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/initialize b/tests/initialize index b333cb3..f74b2de 100755 --- a/tests/initialize +++ b/tests/initialize @@ -118,4 +118,33 @@ init_tests() { SNAP=envtester SNAP_COMMON=/var/snap/"${SNAP}"/common/ -inject_test_app +impl="" + +declare -A impl_map=( + [bash]="env-exporter.sh" + [rust]="env-exporter" +) + +while [[ $# -gt 0 ]]; do + case "$1" in + -i=* | --impl=*) + impl="${1#*=}" + shift + ;; + -i | --impl) + impl="$2" + shift 2 + ;; + *) + help + ;; + esac +done + +if [[ "$impl" != "bash" && "$impl" != "rust" ]]; then + echo "Error: --impl/-i must be either 'bash' or 'rust'" >&2 + help +fi + +inject_test_app "${impl_map[$impl]}" + From bf9b14dcca8039de00b1f2368104da46532031b4 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:09:58 -0300 Subject: [PATCH 12/25] feat: add help function Signed-off-by: Lincoln Wallace --- tests/initialize | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/initialize b/tests/initialize index f74b2de..9800134 100755 --- a/tests/initialize +++ b/tests/initialize @@ -1,5 +1,27 @@ #!/bin/bash +help() { + cat < + $0 --impl= + +Options: + -i, --impl Specify the implementation of the env-exporter program. + Must be either 'bash' or 'rust'. + +Examples: + $0 -i bash + $0 --impl=rust + +Description: + The 'impl' option selects which implementation of the env-exporter program to use. + - 'bash': Uses the Bash-based implementation. + - 'rust': Uses the Rust-based implementation. + +EOF + exit 1 +} + check_syntax() { local snap_app="$1" local env_value="$2" From d9e939c0f66a7f0398d7f100184016fe8d2d6a3a Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:16:18 -0300 Subject: [PATCH 13/25] feat: inject app on GH CI and locally Signed-off-by: Lincoln Wallace --- tests/initialize | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/initialize b/tests/initialize index 9800134..75e3acf 100755 --- a/tests/initialize +++ b/tests/initialize @@ -129,9 +129,9 @@ inject_test_app() { init_tests() { set +u + inject_test_app if [ -z "${GITHUB_ACTIONS}" ]; then set -u - inject_test_app snapcraft -o "${SNAP}".snap snap install "${SNAP}".snap --dangerous fi @@ -139,7 +139,6 @@ init_tests() { SNAP=envtester SNAP_COMMON=/var/snap/"${SNAP}"/common/ - impl="" declare -A impl_map=( From 2018d12b98d652598dfb66440117dcf83de197cb Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:18:12 -0300 Subject: [PATCH 14/25] fix: patch snapcraft.yaml file only on initialization Signed-off-by: Lincoln Wallace --- tests/test-snappyenv | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/tests/test-snappyenv b/tests/test-snappyenv index 2393887..3f4076b 100755 --- a/tests/test-snappyenv +++ b/tests/test-snappyenv @@ -15,17 +15,6 @@ echo "SNAP NAME: ${SNAP}" pushd "$PROJECT_ROOT" || exit 1 -# 'sudo -u "$RUN_AS"' prevents a permission denied error when using yq as snap. -sudo -u "$SUDO_USER" yq '.apps.app2 = { - "environment": { - "env_alias": "app2" - }, - "command-chain": [ - "bin/env-exporter" - ], - "command": "bin/env.sh" -}' -i "snap/snapcraft.yaml" - unsquashfs "${PROJECT_ROOT}/${SNAP}.snap" echo "Check that the env-exporter program is present" From 6971459e5a1d0b4720aa69a04a86a0bcaeea37df Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:18:46 -0300 Subject: [PATCH 15/25] ci: run tests for bash and rust implementation Signed-off-by: Lincoln Wallace --- .github/workflows/test.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5dc3bf4..882a853 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,10 @@ env: jobs: build-and-test: + strategy: + fail-fast: false + matrix: + implementation: [bash, rust] outputs: snap: ${{ steps.snapcraft.outputs.snap }} runs-on: ubuntu-latest @@ -20,8 +24,11 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Implementation + run: "echo ::notice::env-exporter implementation: ${{ matrix.implementation }}" + - name: Initialize tests - run: sudo ./tests/initialize + run: sudo ./tests/initialize -i ${{ matrix.implementation }} - name: Build snap uses: snapcore/action-build@v1 From 52f3a758832d1d21e365ac2d1ef1be7965345c2d Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:33:36 -0300 Subject: [PATCH 16/25] feat: add checker for initializer script Signed-off-by: Lincoln Wallace --- tests/initialize | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/initialize b/tests/initialize index 75e3acf..03e2b3c 100755 --- a/tests/initialize +++ b/tests/initialize @@ -129,7 +129,13 @@ inject_test_app() { init_tests() { set +u - inject_test_app + + if [[ -z "${impl}" ]]; then + echo "Error: first run the initialize script" + help + fi + + inject_test_app "${impl_map[$impl]}" if [ -z "${GITHUB_ACTIONS}" ]; then set -u snapcraft -o "${SNAP}".snap From 91e9943cb75db9da6386ba6ea990febcbc045d3a Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:35:14 -0300 Subject: [PATCH 17/25] test: enable trace Signed-off-by: Lincoln Wallace --- tests/initialize | 3 ++- tests/test-snappyenv | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/initialize b/tests/initialize index 03e2b3c..739950f 100755 --- a/tests/initialize +++ b/tests/initialize @@ -1,5 +1,7 @@ #!/bin/bash +set -x + help() { cat < @@ -174,4 +176,3 @@ if [[ "$impl" != "bash" && "$impl" != "rust" ]]; then fi inject_test_app "${impl_map[$impl]}" - diff --git a/tests/test-snappyenv b/tests/test-snappyenv index 3f4076b..5c5ff78 100755 --- a/tests/test-snappyenv +++ b/tests/test-snappyenv @@ -1,6 +1,6 @@ #!/bin/bash -set -eu +set -eux BASEDIR=$(dirname "$(realpath "$0")") PROJECT_ROOT="$BASEDIR/.." From 33e5721ce88e4d2f33c14106f84ff471b7a67fa4 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 11:38:40 -0300 Subject: [PATCH 18/25] fix: pass key to func instead of value of hashmap Signed-off-by: Lincoln Wallace --- tests/initialize | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/initialize b/tests/initialize index 739950f..649ecdc 100755 --- a/tests/initialize +++ b/tests/initialize @@ -175,4 +175,4 @@ if [[ "$impl" != "bash" && "$impl" != "rust" ]]; then help fi -inject_test_app "${impl_map[$impl]}" +inject_test_app "$impl" From a0f4c1f5d0667fa585fd2f71c583df6dc401f4eb Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 15:10:13 -0300 Subject: [PATCH 19/25] fix: add scape characters to proper evaluate $exporter Signed-off-by: Lincoln Wallace --- tests/initialize | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/initialize b/tests/initialize index 649ecdc..b30dd93 100755 --- a/tests/initialize +++ b/tests/initialize @@ -106,26 +106,26 @@ inject_test_app() { local exporter="${impl_map[$1]}" # Create app1 - sudo -u "$SUDO_USER" yq '.apps.app1 = { - "environment": { - "env_alias": "app1" - }, - "command-chain": [ - "bin/$exporter" - ], - "command": "bin/env.sh" - }' -i "snap/snapcraft.yaml" + sudo -u "$SUDO_USER" yq ".apps.app1 = { + \"environment\": { + \"env_alias\": \"app1\" + }, + \"command-chain\": [ + \"bin/${exporter}\" + ], + \"command\": \"bin/env.sh\" + }" -i "snap/snapcraft.yaml" # Create app2 - sudo -u "$SUDO_USER" yq '.apps.app2 = { - "environment": { - "env_alias": "app2" - }, - "command-chain": [ - "bin/$exporter" - ], - "command": "bin/env.sh" - }' -i "snap/snapcraft.yaml" + sudo -u "$SUDO_USER" yq ".apps.app2 = { + \"environment\": { + \"env_alias\": \"app2\" + }, + \"command-chain\": [ + \"bin/${exporter}\" + ], + \"command\": \"bin/env.sh\" + }" -i "snap/snapcraft.yaml" } From efa3e8320858cbfe4d7212ba23cae841121a8a43 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 15:17:46 -0300 Subject: [PATCH 20/25] test: verify script||binary inside snap bundle - Change test metadata to avoid confusion Signed-off-by: Lincoln Wallace --- tests/test-snappyenv | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test-snappyenv b/tests/test-snappyenv index 5c5ff78..e564428 100755 --- a/tests/test-snappyenv +++ b/tests/test-snappyenv @@ -18,7 +18,7 @@ pushd "$PROJECT_ROOT" || exit 1 unsquashfs "${PROJECT_ROOT}/${SNAP}.snap" echo "Check that the env-exporter program is present" -[ -f squashfs-root/bin/env-exporter ] || fail +[ -f squashfs-root/bin/env-exporter ] || [ -f squashfs-root/bin/env-exporter.sh ] || fail echo "Check that the exec-env script is present" [ -f squashfs-root/bin/env.sh ] || fail @@ -29,7 +29,7 @@ echo 'HELLO_WORLD="Hello World"' >>"$SNAP_COMMON"/global.env echo "Load global envfile" snap set "${SNAP}" envfile="$SNAP_COMMON"/global.env -echo "[TEST] - Check if the global envfile is loaded the app using Rust snappy-env programs" +echo "[TEST] - Check if the global envfile is loaded the app using snappy-env programs" check_env_exist "${SNAP}.app1" "HELLO_WORLD" || fail check_env_value "${SNAP}.app1" "HELLO_WORLD" "Hello World" || fail @@ -37,8 +37,8 @@ check_env_exist "${SNAP}.app2" "HELLO_WORLD" || fail check_env_value "${SNAP}.app2" "HELLO_WORLD" "Hello World" || fail echo -e "\n[envtester] Creating app-specific envfile" -echo 'SCOPED=RustVersion' >>"$SNAP_COMMON"/envs.env -echo 'SCOPED=Rust2Version' >>"$SNAP_COMMON"/envs2.env +echo 'SCOPED=AppVersion' >>"$SNAP_COMMON"/envs.env +echo 'SCOPED=App2Version' >>"$SNAP_COMMON"/envs2.env echo "Load app-specific envfile" snap set "${SNAP}" apps.app1.envfile="$SNAP_COMMON"/envs.env @@ -46,10 +46,10 @@ snap set "${SNAP}" apps.app2.envfile="$SNAP_COMMON"/envs2.env echo "[TEST] - Check if the app-specific envfile is loaded for the apps" check_env_exist "${SNAP}.app1" "SCOPED" || fail -check_env_value "${SNAP}.app1" "SCOPED" "RustVersion" || fail +check_env_value "${SNAP}.app1" "SCOPED" "AppVersion" || fail check_env_exist "${SNAP}.app2" "SCOPED" || fail -check_env_value "${SNAP}.app2" "SCOPED" "Rust2Version" || fail +check_env_value "${SNAP}.app2" "SCOPED" "App2Version" || fail echo -e "\n[envtester] Setting global env variable" From 1a80d92337e2624211b7a8f84f31818dcc7d7388 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 17:50:56 -0300 Subject: [PATCH 21/25] feat: only patch when running initialize script Signed-off-by: Lincoln Wallace --- tests/initialize | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/initialize b/tests/initialize index b30dd93..228dd5e 100755 --- a/tests/initialize +++ b/tests/initialize @@ -137,7 +137,6 @@ init_tests() { help fi - inject_test_app "${impl_map[$impl]}" if [ -z "${GITHUB_ACTIONS}" ]; then set -u snapcraft -o "${SNAP}".snap From 6e1242b92c6aa2bd3baf1919f104059e8c10618c Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 17:54:27 -0300 Subject: [PATCH 22/25] feat: avoid name conflict Signed-off-by: Lincoln Wallace --- .github/workflows/test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 882a853..fdead15 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,9 +8,6 @@ on: # Allow manual trigger workflow_dispatch: -env: - SNAP: envtester_${{ github.run_id}}.snap - jobs: build-and-test: strategy: @@ -40,7 +37,7 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: ${{ env.SNAP }} + name: envtester_${{ github.run_id}}_${{matrix.implementation}}.snap path: ${{ steps.snapcraft.outputs.snap }} if-no-files-found: error From a59ba255ddea3201ce0026aef08ff01447107386 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Tue, 8 Apr 2025 18:07:12 -0300 Subject: [PATCH 23/25] feat: set impl on test-snappyenv Signed-off-by: Lincoln Wallace --- .github/workflows/test.yml | 4 ++-- tests/initialize | 12 ++++++++---- tests/test-snappyenv | 3 +++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fdead15..56ba913 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,9 +37,9 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@v4 with: - name: envtester_${{ github.run_id}}_${{matrix.implementation}}.snap + name: envtester_${{ github.run_id }}_${{ matrix.implementation }}.snap path: ${{ steps.snapcraft.outputs.snap }} if-no-files-found: error - name: Run tests - run: sudo ./tests/test-snappyenv + run: sudo ./tests/test-snappyenv ${{ matrix.implementation }} diff --git a/tests/initialize b/tests/initialize index 228dd5e..dd7944e 100755 --- a/tests/initialize +++ b/tests/initialize @@ -144,6 +144,13 @@ init_tests() { fi } +check_impl() { + if [[ "$impl" != "bash" && "$impl" != "rust" ]]; then + echo "Error: --impl/-i must be either 'bash' or 'rust'" >&2 + help + fi +} + SNAP=envtester SNAP_COMMON=/var/snap/"${SNAP}"/common/ impl="" @@ -169,9 +176,6 @@ while [[ $# -gt 0 ]]; do esac done -if [[ "$impl" != "bash" && "$impl" != "rust" ]]; then - echo "Error: --impl/-i must be either 'bash' or 'rust'" >&2 - help -fi +check_impl inject_test_app "$impl" diff --git a/tests/test-snappyenv b/tests/test-snappyenv index e564428..f98109c 100755 --- a/tests/test-snappyenv +++ b/tests/test-snappyenv @@ -7,6 +7,9 @@ PROJECT_ROOT="$BASEDIR/.." . $PROJECT_ROOT/tests/initialize +impl=$1 +check_impl + check_root clean init_tests From d73a60b12bf322754dafaccb35eb5b66982cd110 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Wed, 9 Apr 2025 09:15:29 -0300 Subject: [PATCH 24/25] many: refact scripts Signed-off-by: Lincoln Wallace --- tests/common | 131 ++++++++++++++++++++++++++++++++++++++++ tests/initialize | 140 ++----------------------------------------- tests/test-snappyenv | 6 +- 3 files changed, 138 insertions(+), 139 deletions(-) create mode 100755 tests/common diff --git a/tests/common b/tests/common new file mode 100755 index 0000000..5726340 --- /dev/null +++ b/tests/common @@ -0,0 +1,131 @@ + +declare -A impl_map=( + [bash]="env-exporter.sh" + [rust]="env-exporter" +) + +SNAP=envtester +SNAP_COMMON=/var/snap/"${SNAP}"/common/ + +check_syntax() { + local snap_app="$1" + local env_value="$2" + if eval "$snap_app" | grep -q "^${env_value}="; then + echo -e "\n[ERROR] Value '$env_name' SHOULD NOT BE set.\n" + return 1 + fi + return 0 +} + +check_env_exist() { + local snap_app="$1" + local env_name="$2" + + if ! eval "$snap_app" | grep -q "^${env_name}="; then + echo -e "\n[ERROR] Environment variable '$env_name' is not set, for the app: $snap_app.\n" + return 1 + fi +} + +check_env_not_exist() { + + local snap_app="$1" + local env_name="$2" + + if eval "$snap_app" | grep -q "^${env_name}="; then + echo -e "\n[ERROR] Environment variable '$env_name' SHOULD NOT be set, for the app: $snap_app.\n" + return 1 + fi +} + +check_env_value() { + local snap_app="$1" + local env_name="$2" + local exp_value="$3" + local actual_value + + if [ -z "$env_name" ]; then + echo -e "\n\nHERE HERE\n\n " + empty=$("$snap_app" | grep "=${exp_value}") + [ -z "$empty" ] || return 1 + fi + actual_value=$("$snap_app" | grep "^${env_name}=" | cut -d'=' -f2-) + if [ "$actual_value" != "$exp_value" ]; then + echo -e "\n[ERROR] Environment variable '$env_name' does not match the expected value, for the app: $snap_app" + echo -e "[ERROR] Expected: '$env_name=$exp_value', but got: '$env_name=$actual_value'\n" + return 1 + fi +} + +check_root() { + if [ "$USER" != "root" ]; then + echo -e "Please run as root.\n" + exit 1 + fi +} + +clean() { + echo "Cleaning..." + snap remove --purge "${SNAP}" + git restore snap/snapcraft.yaml + sudo chown $SUDO_USER:$SUDO_USER snap/snapcraft.yaml + + rm -rf squashfs-root +} + +fail() { + clean + exit 1 +} + +inject_test_app() { + clean + sudo snap install yq + + if [[ -z "${impl_map[$1]}" ]]; then + echo "Error: unknown implementation '$1'" + help + fi + + local exporter="${impl_map[$1]}" + + # Create app1 + sudo -u "$SUDO_USER" yq ".apps.app1 = { + \"environment\": { + \"env_alias\": \"app1\" + }, + \"command-chain\": [ + \"bin/${exporter}\" + ], + \"command\": \"bin/env.sh\" + }" -i "snap/snapcraft.yaml" + + # Create app2 + sudo -u "$SUDO_USER" yq ".apps.app2 = { + \"environment\": { + \"env_alias\": \"app2\" + }, + \"command-chain\": [ + \"bin/${exporter}\" + ], + \"command\": \"bin/env.sh\" + }" -i "snap/snapcraft.yaml" + +} + +check_impl() { + if [[ "$1" != "bash" && "$1" != "rust" ]]; then + echo "Error: --impl/-i must be either 'bash' or 'rust'" >&2 + help + fi +} + +init_tests() { + set +u + + if [ -z "${GITHUB_ACTIONS}" ]; then + set -u + snapcraft -o "${SNAP}".snap + snap install "${SNAP}".snap --dangerous + fi +} \ No newline at end of file diff --git a/tests/initialize b/tests/initialize index dd7944e..975ba41 100755 --- a/tests/initialize +++ b/tests/initialize @@ -2,6 +2,11 @@ set -x +BASEDIR=$(dirname "$(realpath "$0")") +PROJECT_ROOT="$BASEDIR/.." + +. $PROJECT_ROOT/tests/common + help() { cat < @@ -24,142 +29,9 @@ EOF exit 1 } -check_syntax() { - local snap_app="$1" - local env_value="$2" - if eval "$snap_app" | grep -q "^${env_value}="; then - echo -e "\n[ERROR] Value '$env_name' SHOULD NOT BE set.\n" - return 1 - fi - return 0 -} - -check_env_exist() { - local snap_app="$1" - local env_name="$2" - - if ! eval "$snap_app" | grep -q "^${env_name}="; then - echo -e "\n[ERROR] Environment variable '$env_name' is not set, for the app: $snap_app.\n" - return 1 - fi -} - -check_env_not_exist() { - - local snap_app="$1" - local env_name="$2" - - if eval "$snap_app" | grep -q "^${env_name}="; then - echo -e "\n[ERROR] Environment variable '$env_name' SHOULD NOT be set, for the app: $snap_app.\n" - return 1 - fi -} - -check_env_value() { - local snap_app="$1" - local env_name="$2" - local exp_value="$3" - local actual_value - - if [ -z "$env_name" ]; then - echo -e "\n\nHERE HERE\n\n " - empty=$("$snap_app" | grep "=${exp_value}") - [ -z "$empty" ] || return 1 - fi - actual_value=$("$snap_app" | grep "^${env_name}=" | cut -d'=' -f2-) - if [ "$actual_value" != "$exp_value" ]; then - echo -e "\n[ERROR] Environment variable '$env_name' does not match the expected value, for the app: $snap_app" - echo -e "[ERROR] Expected: '$env_name=$exp_value', but got: '$env_name=$actual_value'\n" - return 1 - fi -} - -check_root() { - if [ "$USER" != "root" ]; then - echo -e "Please run as root.\n" - exit 1 - fi -} - -clean() { - echo "Cleaning..." - snap remove --purge "${SNAP}" - git restore snap/snapcraft.yaml - sudo chown $SUDO_USER:$SUDO_USER snap/snapcraft.yaml - - rm -rf squashfs-root -} - -fail() { - clean - exit 1 -} - -inject_test_app() { - sudo snap install yq - - if [[ -z "${impl_map[$1]}" ]]; then - echo "Error: unknown implementation '$1'" - help - fi - - local exporter="${impl_map[$1]}" - - # Create app1 - sudo -u "$SUDO_USER" yq ".apps.app1 = { - \"environment\": { - \"env_alias\": \"app1\" - }, - \"command-chain\": [ - \"bin/${exporter}\" - ], - \"command\": \"bin/env.sh\" - }" -i "snap/snapcraft.yaml" - - # Create app2 - sudo -u "$SUDO_USER" yq ".apps.app2 = { - \"environment\": { - \"env_alias\": \"app2\" - }, - \"command-chain\": [ - \"bin/${exporter}\" - ], - \"command\": \"bin/env.sh\" - }" -i "snap/snapcraft.yaml" - -} -init_tests() { - set +u - - if [[ -z "${impl}" ]]; then - echo "Error: first run the initialize script" - help - fi - - if [ -z "${GITHUB_ACTIONS}" ]; then - set -u - snapcraft -o "${SNAP}".snap - snap install "${SNAP}".snap --dangerous - fi -} - -check_impl() { - if [[ "$impl" != "bash" && "$impl" != "rust" ]]; then - echo "Error: --impl/-i must be either 'bash' or 'rust'" >&2 - help - fi -} - -SNAP=envtester -SNAP_COMMON=/var/snap/"${SNAP}"/common/ impl="" -declare -A impl_map=( - [bash]="env-exporter.sh" - [rust]="env-exporter" -) - while [[ $# -gt 0 ]]; do case "$1" in -i=* | --impl=*) @@ -176,6 +48,6 @@ while [[ $# -gt 0 ]]; do esac done -check_impl +check_impl "$impl" inject_test_app "$impl" diff --git a/tests/test-snappyenv b/tests/test-snappyenv index f98109c..71e6d60 100755 --- a/tests/test-snappyenv +++ b/tests/test-snappyenv @@ -5,13 +5,9 @@ set -eux BASEDIR=$(dirname "$(realpath "$0")") PROJECT_ROOT="$BASEDIR/.." -. $PROJECT_ROOT/tests/initialize - -impl=$1 -check_impl +. $PROJECT_ROOT/tests/common check_root -clean init_tests echo "SNAP NAME: ${SNAP}" From e951af2f72c52021c9b306f4ec55f6a81f626492 Mon Sep 17 00:00:00 2001 From: Lincoln Wallace Date: Wed, 9 Apr 2025 09:16:39 -0300 Subject: [PATCH 25/25] feat!: don't pass impl set to test script Signed-off-by: Lincoln Wallace --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 56ba913..bbd2d1b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,4 +42,4 @@ jobs: if-no-files-found: error - name: Run tests - run: sudo ./tests/test-snappyenv ${{ matrix.implementation }} + run: sudo ./tests/test-snappyenv