diff --git a/README.md b/README.md index 409706f..7e78aeb 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,13 @@ regular file owned by `root:root` with mode `0755`. ## Validation The integration driver installs pinned collection dependencies, runs syntax -checking and ansible-lint, and verifies the default release and idempotence. It -also covers a missing binary, a caller-supplied Go executable with dependency -management disabled, metadata drift without a build, selection of the previous -release, restoration of the default release, and platform failures before -application state is created. The suite mutates only +checking and ansible-lint, and covers default smoke use with clean repeated +convergence. It also verifies an explicitly selected Seriatim release and +combines missing-binary recovery with a caller-supplied Go executable while +dependency management is disabled. The suite mutates only `/usr/local/src/seriatim`, `/usr/local/bin/seriatim`, and paths inside its -private temporary directory, and leaves the default release installed: +private temporary directory, and restores the default deployment during +cleanup: ```sh tests/integration diff --git a/tests/integration b/tests/integration index c709b69..a709ad0 100755 --- a/tests/integration +++ b/tests/integration @@ -11,12 +11,7 @@ export ANSIBLE_ROLES_PATH="$(dirname "$repository_root")" inventory="$repository_root/tests/inventory" converge="$repository_root/tests/converge.yml" -verify="$repository_root/tests/verify.yml" -unsupported="$repository_root/tests/unsupported.yml" ansible_playbook="$workspace_venv/bin/ansible-playbook" -default_commit=0fc92f364316c874d366b00cdc884a33e1900b25 -previous_commit=9202ccddb962ab499f0772d3c01efdf2ff703077 -source_dir=/usr/local/src/seriatim binary_path=/usr/local/bin/seriatim cleanup() { @@ -32,117 +27,49 @@ require_clean_recap() { grep -Eq 'changed=0 .*failed=0' "$1" } -require_changed_recap() { - grep -Eq 'changed=[1-9][0-9]* .*failed=0' "$1" -} - run_converge() { output_file=$1 shift "$ansible_playbook" -i "$inventory" "$@" "$converge" | tee "$output_file" } -verify_release() { - expected_version=$1 - expected_commit=$2 - "$ansible_playbook" -i "$inventory" \ - -e "seriatim_expected_version=$expected_version" \ - -e "seriatim_expected_commit=$expected_commit" \ - "$verify" -} - cd "$repository_root" "$workspace_venv/bin/ansible-galaxy" collection install \ -r collections/requirements.yml \ -p "$ANSIBLE_COLLECTIONS_PATH" "$ansible_playbook" -i "$inventory" --syntax-check "$converge" -"$workspace_venv/bin/ansible-lint" "$converge" "$verify" "$unsupported" +"$workspace_venv/bin/ansible-lint" "$converge" baseline_log="$test_tmp/baseline.log" run_converge "$baseline_log" -verify_release v1.5.0 "$default_commit" +"$binary_path" --version baseline_repeat_log="$test_tmp/baseline-repeat.log" run_converge "$baseline_repeat_log" require_clean_recap "$baseline_repeat_log" -sudo rm -f -- "$binary_path" -missing_binary_log="$test_tmp/missing-binary.log" -run_converge "$missing_binary_log" -require_changed_recap "$missing_binary_log" -grep -A1 -E 'TASK .*Build Seriatim' "$missing_binary_log" | grep -q '^changed:' -missing_binary_repeat_log="$test_tmp/missing-binary-repeat.log" -run_converge "$missing_binary_repeat_log" -require_clean_recap "$missing_binary_repeat_log" +selected_release_log="$test_tmp/selected-release.log" +run_converge "$selected_release_log" -e seriatim_version=v1.4.0 +[[ "$("$binary_path" --version)" == 'seriatim version v1.4.0' ]] custom_go_binary="$test_tmp/go" -ln -s /snap/bin/go "$custom_go_binary" +custom_go_invocations="$test_tmp/go-invocations.log" +printf '%s\n' \ + '#!/usr/bin/env bash' \ + 'set -euo pipefail' \ + "printf '%s\\n' \"\$*\" >> '$custom_go_invocations'" \ + 'exec /snap/bin/go "$@"' > "$custom_go_binary" +chmod 0755 "$custom_go_binary" sudo rm -f -- "$binary_path" -custom_go_log="$test_tmp/custom-go.log" -run_converge "$custom_go_log" \ +recovery_log="$test_tmp/recovery.log" +run_converge "$recovery_log" \ + -e seriatim_version=v1.4.0 \ -e '{"seriatim_manage_build_dependencies": false}' \ -e "seriatim_go_binary=$custom_go_binary" -require_changed_recap "$custom_go_log" -grep -A1 -E 'TASK .*Build Seriatim' "$custom_go_log" | grep -q '^changed:' -verify_release v1.5.0 "$default_commit" -custom_go_repeat_log="$test_tmp/custom-go-repeat.log" -run_converge "$custom_go_repeat_log" \ +grep -q . "$custom_go_invocations" +[[ "$("$binary_path" --version)" == 'seriatim version v1.4.0' ]] +recovery_repeat_log="$test_tmp/recovery-repeat.log" +run_converge "$recovery_repeat_log" \ + -e seriatim_version=v1.4.0 \ -e '{"seriatim_manage_build_dependencies": false}' \ -e "seriatim_go_binary=$custom_go_binary" -require_clean_recap "$custom_go_repeat_log" - -sudo chmod 0700 "$binary_path" -metadata_log="$test_tmp/metadata.log" -run_converge "$metadata_log" -require_changed_recap "$metadata_log" -grep -A1 -E 'TASK .*Build Seriatim' "$metadata_log" | grep -q '^skipping:' -grep -A3 -E 'TASK .*Converge installed metadata' "$metadata_log" | \ - grep -q "^changed:.*'path': '$binary_path'" -metadata_repeat_log="$test_tmp/metadata-repeat.log" -run_converge "$metadata_repeat_log" -require_clean_recap "$metadata_repeat_log" - -previous_release_log="$test_tmp/previous-release.log" -run_converge "$previous_release_log" -e seriatim_version=v1.4.0 -require_changed_recap "$previous_release_log" -verify_release v1.4.0 "$previous_commit" -previous_repeat_log="$test_tmp/previous-repeat.log" -run_converge "$previous_repeat_log" -e seriatim_version=v1.4.0 -require_clean_recap "$previous_repeat_log" - -restored_release_log="$test_tmp/restored-release.log" -run_converge "$restored_release_log" -require_changed_recap "$restored_release_log" -verify_release v1.5.0 "$default_commit" -restored_repeat_log="$test_tmp/restored-repeat.log" -run_converge "$restored_repeat_log" -require_clean_recap "$restored_repeat_log" - -platform_cases=( - 'Debian 26.04 x86_64 distribution' - 'Ubuntu 24.04 x86_64 release' - 'Ubuntu 26.04 riscv64 architecture' -) -for platform_case in "${platform_cases[@]}"; do - read -r distribution release architecture label <<<"$platform_case" - case_root="$test_tmp/unsupported-$label" - case_source="$case_root/source" - case_binary="$case_root/bin/seriatim" - case_log="$test_tmp/unsupported-$label.log" - if "$ansible_playbook" -i "$inventory" \ - -e "test_distribution=$distribution" \ - -e "test_distribution_version=$release" \ - -e "test_architecture=$architecture" \ - -e "seriatim_source_dir=$case_source" \ - -e "seriatim_binary_path=$case_binary" \ - "$unsupported" | tee "$case_log"; then - echo "Unsupported $label case unexpectedly succeeded" >&2 - exit 1 - fi - grep -Eq 'failed=1' "$case_log" - [[ ! -e "$case_source" ]] - [[ ! -e "$case_binary" ]] -done - -[[ "$("$binary_path" --version)" == 'seriatim version v1.5.0' ]] -[[ "$(sudo git -C "$source_dir" rev-parse HEAD)" == "$default_commit" ]] -[[ "$(sudo stat -c '%U:%G %a' "$binary_path")" == 'root:root 755' ]] +require_clean_recap "$recovery_repeat_log" diff --git a/tests/unsupported.yml b/tests/unsupported.yml deleted file mode 100644 index dd8b1e3..0000000 --- a/tests/unsupported.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -- name: Exercise Seriatim platform mutation guard - hosts: seriatim - gather_facts: false - vars: - ansible_facts: - distribution: "{{ test_distribution }}" - distribution_version: "{{ test_distribution_version }}" - architecture: "{{ test_architecture }}" - roles: - - role: ansible-role-seriatim diff --git a/tests/verify.yml b/tests/verify.yml deleted file mode 100644 index defaccf..0000000 --- a/tests/verify.yml +++ /dev/null @@ -1,73 +0,0 @@ ---- -- name: Verify the Seriatim installation - hosts: localhost - connection: local - gather_facts: false - become: true - vars: - seriatim_expected_commit: 0fc92f364316c874d366b00cdc884a33e1900b25 - seriatim_expected_version: v1.5.0 - seriatim_source_dir: /usr/local/src/seriatim - seriatim_binary_path: /usr/local/bin/seriatim - tasks: - - name: Inspect the source directory - ansible.builtin.stat: - path: "{{ seriatim_source_dir }}" - register: seriatim_source - - - name: Find incorrectly owned source entries - ansible.builtin.command: - argv: - - find - - "{{ seriatim_source_dir }}" - - ( - - -not - - -user - - root - - -or - - -not - - -group - - root - - ) - - -print - - -quit - register: seriatim_source_ownership - changed_when: false - - - name: Read the selected source commit - ansible.builtin.command: - argv: - - git - - -C - - "{{ seriatim_source_dir }}" - - rev-parse - - HEAD - register: seriatim_source_commit - changed_when: false - - - name: Inspect the installed binary - ansible.builtin.stat: - path: "{{ seriatim_binary_path }}" - register: seriatim_binary - - - name: Read the installed version - ansible.builtin.command: - argv: - - "{{ seriatim_binary_path }}" - - --version - register: seriatim_version_output - changed_when: false - - - name: Assert the installation contract - ansible.builtin.assert: - that: - - seriatim_source.stat.isdir - - seriatim_source.stat.pw_name == "root" - - seriatim_source.stat.gr_name == "root" - - seriatim_source_ownership.stdout == "" - - seriatim_source_commit.stdout == seriatim_expected_commit - - seriatim_binary.stat.isreg - - seriatim_binary.stat.pw_name == "root" - - seriatim_binary.stat.gr_name == "root" - - seriatim_binary.stat.mode == "0755" - - seriatim_version_output.stdout == "seriatim version " ~ seriatim_expected_version