Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
74f5144
feat: Add func to detect nested values and drop it
locnnil Apr 4, 2025
3a7777d
feat: add context to error
locnnil Apr 7, 2025
e99521d
fix: use right RegEx
locnnil Apr 7, 2025
df71dd2
debug: add trace
locnnil Apr 7, 2025
9b74b4a
refact: add missing quotations
locnnil Apr 7, 2025
6e78601
feat: revert prev regex
locnnil Apr 7, 2025
06cf2cd
feat: exit 1 on error
locnnil Apr 7, 2025
70571dd
feat!: drop trace
locnnil Apr 8, 2025
deff3d5
feat: change app names to app1 and app2
locnnil Apr 8, 2025
891013c
feat: patch snapcraft.yaml with app1 and app2
locnnil Apr 8, 2025
f9ec1f3
feat: add -i/--impl parameter to set rust or bash implementation
locnnil Apr 8, 2025
bf9b14d
feat: add help function
locnnil Apr 8, 2025
d9e939c
feat: inject app on GH CI and locally
locnnil Apr 8, 2025
2018d12
fix: patch snapcraft.yaml file only on initialization
locnnil Apr 8, 2025
6971459
ci: run tests for bash and rust implementation
locnnil Apr 8, 2025
52f3a75
feat: add checker for initializer script
locnnil Apr 8, 2025
91e9943
test: enable trace
locnnil Apr 8, 2025
33e5721
fix: pass key to func instead of value of hashmap
locnnil Apr 8, 2025
a0f4c1f
fix: add scape characters to proper evaluate $exporter
locnnil Apr 8, 2025
efa3e83
test: verify script||binary inside snap bundle
locnnil Apr 8, 2025
1a80d92
feat: only patch when running initialize script
locnnil Apr 8, 2025
6e1242b
feat: avoid name conflict
locnnil Apr 8, 2025
a59ba25
feat: set impl on test-snappyenv
locnnil Apr 8, 2025
d73a60b
many: refact scripts
locnnil Apr 9, 2025
e951af2
feat!: don't pass impl set to test script
locnnil Apr 9, 2025
63cacca
Merge branch 'main' into improve-tests
locnnil May 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@ on:
# Allow manual trigger
workflow_dispatch:

env:
SNAP: envtester_${{ github.run_id}}.snap

jobs:
build-and-test:
strategy:
fail-fast: false
matrix:
implementation: [bash, rust]
outputs:
snap: ${{ steps.snapcraft.outputs.snap }}
runs-on: ubuntu-latest
steps:
- 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
Expand All @@ -33,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

Expand Down
1 change: 1 addition & 0 deletions env-exporter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ json_to_hash_table() {
local nested=$(catch_nested_json "$json_input")
err "Nested snap options keys aren't supported:\n$nested"
json_input=$(strip_nested_json_keys "$json_input")

fi

json_input=$(echo "$json_input" | sed 's/[{}]//g' | tr -d '[:space:]')
Expand Down
131 changes: 131 additions & 0 deletions tests/common
Original file line number Diff line number Diff line change
@@ -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
}
123 changes: 38 additions & 85 deletions tests/initialize
Original file line number Diff line number Diff line change
@@ -1,100 +1,53 @@
#!/bin/bash

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"
set -x

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
}
BASEDIR=$(dirname "$(realpath "$0")")
PROJECT_ROOT="$BASEDIR/.."

check_env_not_exist() {
. $PROJECT_ROOT/tests/common

local snap_app="$1"
local env_name="$2"
help() {
cat <<EOF
Usage: $0 -i <impl>
$0 --impl=<impl>

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
}
Options:
-i, --impl <impl> Specify the implementation of the env-exporter program.
Must be either 'bash' or 'rust'.

check_env_value() {
local snap_app="$1"
local env_name="$2"
local exp_value="$3"
local actual_value
Examples:
$0 -i bash
$0 --impl=rust

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
}
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.

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
EOF
exit 1
}

inject_test_app() {
sudo snap install yq
sudo -u "$SUDO_USER" yq '.apps.app-rust-2 = {
"environment": {
"env_alias": "app-rust-2"
},
"command-chain": [
"bin/env-exporter"
],
"command": "bin/env.sh"
}' -i "snap/snapcraft.yaml"
}

init_tests() {
set +u
if [ -z "${GITHUB_ACTIONS}" ]; then
set -u
inject_test_app
snapcraft -o "${SNAP}".snap
snap install "${SNAP}".snap --dangerous
fi
}
impl=""

while [[ $# -gt 0 ]]; do
case "$1" in
-i=* | --impl=*)
impl="${1#*=}"
shift
;;
-i | --impl)
impl="$2"
shift 2
;;
*)
help
;;
esac
done

SNAP=envtester
SNAP_COMMON=/var/snap/"${SNAP}"/common/
check_impl "$impl"
Comment on lines +10 to +51

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines 10 to 49 logically belong to the common script, where the implementation value is verified and consumed.


inject_test_app
inject_test_app "$impl"
Loading
Loading