#!/usr/bin/env bash set -euo pipefail ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) # shellcheck source=tests/lib/assert.sh source "${ROOT_DIR}/tests/lib/assert.sh" TMP_DIR=$(mktemp -d) trap 'rm -rf "${TMP_DIR}"' EXIT export IPF_STORAGE_DIR="${TMP_DIR}/storage" export IPF_STORAGE_DB="${IPF_STORAGE_DIR}/rules.db" export IPF_LOCK_FILE="${IPF_STORAGE_DIR}/.lock" # shellcheck source=lib/storage.sh source "${ROOT_DIR}/lib/storage.sh" storage_init [[ -f ${IPF_STORAGE_DB} ]] || fail 'storage_init should create rules db' line1='uuid=a1|proto=tcp|lport=80|tip=127.0.0.1|tport=8080|ipver=4|desc=one|created=2026-04-17T00:00:00+0800' line2='uuid=b2|proto=udp|lport=53|tip=127.0.0.1|tport=5353|ipver=4|desc=two|created=2026-04-17T00:00:01+0800' line3='uuid=c3|proto=both|lport=22|tip=127.0.0.1,::1|tport=22|ipver=both|desc=three|created=2026-04-17T00:00:02+0800' storage_add "${line1}" storage_add "${line2}" storage_add "${line3}" assert_eq '3' "$(storage_count)" 'storage_count should reflect inserted lines' mapfile -t listed < <(storage_list) assert_eq "${line1}" "${listed[0]}" 'storage_list should preserve insertion order' assert_eq "${line2}" "${listed[1]}" 'storage_list should preserve second line' assert_eq "${line3}" "${listed[2]}" 'storage_list should preserve third line' assert_eq "${line2}" "$(storage_get 'b2')" 'storage_get should find existing uuid' if storage_get 'missing' >/dev/null 2>&1; then fail 'storage_get should fail for missing uuid' fi storage_delete 'b2' assert_eq '2' "$(storage_count)" 'storage_delete should remove one line' if storage_delete 'b2' >/dev/null 2>&1; then fail 'storage_delete should fail for missing uuid' fi assert_eq '2' "$(storage_count)" 'storage_delete failure should keep file unchanged' assert_eq '22' "$(storage_parse "${line3}" tport)" 'storage_parse should extract requested field' pass 'test_storage.sh'