Some checks failed
CI / skinny-install (aco) (push) Successful in 1m18s
CI / skinny-install (api) (push) Successful in 40s
CI / skinny-install (bcda) (push) Successful in 35s
CI / skinny-install (bib) (push) Successful in 38s
CI / skinny-install (cli) (push) Successful in 46s
CI / skinny-install (conf) (push) Successful in 36s
CI / skinny-install (opps) (push) Successful in 38s
CI / skinny-install (pfs) (push) Successful in 47s
CI / skinny-install (rex) (push) Successful in 35s
Infra CI / notebooks (push) Successful in 3m17s
CI / lint-test (push) Failing after 3m30s
CI / skinny-install (bls) (push) Successful in 34s
CI / skinny-install (ccw) (push) Successful in 45s
CI / skinny-install (cms) (push) Successful in 32s
CI / skinny-install (perf) (push) Successful in 43s
Deploy / build-scan-report (push) Has been cancelled
Infra CI / docs (push) Failing after 20s
Infra CI / api (push) Successful in 16s
Infra CI / mc (push) Successful in 12s
Package Supply Chain / pkg-supply-chain (push) Successful in 1m27s
Infra CI / zotero (push) Successful in 6m10s
215 lines
5.5 KiB
Bash
215 lines
5.5 KiB
Bash
#!/usr/bin/env bats
|
|
# Integration tests — full enrollment flow simulation
|
|
|
|
load test_helper
|
|
|
|
setup() {
|
|
setup_test_work
|
|
source_nanny_functions
|
|
mkdir -p "${TEST_WORK}/ssh-keys"
|
|
}
|
|
|
|
teardown() {
|
|
teardown_test_work
|
|
}
|
|
|
|
# ─── Full state machine walkthrough ───
|
|
|
|
@test "complete enrollment produces all required state entries" {
|
|
local all_steps=(
|
|
"phase1_init"
|
|
"drive_sata_1" "drive_sata_2" "drive_sata_3"
|
|
"drive_sata_4" "drive_sata_5" "drive_sata_6"
|
|
"drive_nvme" "drive_hdd"
|
|
"phase1_resolver"
|
|
"yubikey_1" "yubikey_2"
|
|
"phase2_authkeys"
|
|
"cf_account" "cf_tunnel" "cf_routes" "cf_access"
|
|
"cf_ssl" "cf_api_token" "cf_cert" "cf_warp"
|
|
"cf_rustfs_creds" "cf_network"
|
|
)
|
|
|
|
for step in "${all_steps[@]}"; do
|
|
state_mark "$step"
|
|
done
|
|
|
|
local total
|
|
total=$(wc -l < "$STATE")
|
|
assert_equal "$total" "${#all_steps[@]}"
|
|
|
|
for step in "${all_steps[@]}"; do
|
|
run state_done "$step"
|
|
assert_success
|
|
done
|
|
}
|
|
|
|
@test "partial completion: drives done, yubikeys pending" {
|
|
state_mark "phase1_init"
|
|
for i in 1 2 3 4 5 6; do
|
|
state_mark "drive_sata_${i}"
|
|
done
|
|
state_mark "drive_nvme"
|
|
state_mark "drive_hdd"
|
|
state_mark "phase1_resolver"
|
|
|
|
# Drives complete
|
|
for i in 1 2 3 4 5 6; do
|
|
run state_done "drive_sata_${i}"
|
|
assert_success
|
|
done
|
|
|
|
# YubiKeys pending
|
|
run state_done "yubikey_1"
|
|
assert_failure
|
|
run state_done "yubikey_2"
|
|
assert_failure
|
|
|
|
# Cloudflare pending
|
|
run state_done "cf_account"
|
|
assert_failure
|
|
}
|
|
|
|
@test "partial completion: drives + keys done, cloudflare pending" {
|
|
state_mark "phase1_init"
|
|
for i in 1 2 3 4 5 6; do
|
|
state_mark "drive_sata_${i}"
|
|
done
|
|
state_mark "drive_nvme"
|
|
state_mark "drive_hdd"
|
|
state_mark "phase1_resolver"
|
|
state_mark "yubikey_1"
|
|
state_mark "yubikey_2"
|
|
state_mark "phase2_authkeys"
|
|
|
|
# Everything before CF done
|
|
run state_done "phase2_authkeys"
|
|
assert_success
|
|
|
|
# CF steps pending
|
|
run state_done "cf_account"
|
|
assert_failure
|
|
run state_done "cf_tunnel"
|
|
assert_failure
|
|
}
|
|
|
|
# ─── Full output file set ───
|
|
|
|
@test "complete enrollment creates all output files" {
|
|
# Simulate full enrollment outputs
|
|
cat > "$CONF" << 'DRIVES'
|
|
DRIVE_SATA_1=S001|WD Blue|none|2000000000000|sata|enrolled_via=usb
|
|
DRIVE_SATA_2=S002|WD Blue|none|2000000000000|sata|enrolled_via=usb
|
|
DRIVE_SATA_3=S003|WD Blue|none|2000000000000|sata|enrolled_via=usb
|
|
DRIVE_SATA_4=S004|WD Blue|none|2000000000000|sata|enrolled_via=usb
|
|
DRIVE_SATA_5=S005|WD Blue|none|2000000000000|sata|enrolled_via=usb
|
|
DRIVE_SATA_6=S006|WD Blue|none|2000000000000|sata|enrolled_via=usb
|
|
DRIVE_NVME_DOCKER=N001|SN770|none|2000000000000|nvme|enrolled_via=usb
|
|
DRIVE_HDD_BACKUP=H001|WD Red|none|4000000000000|sata|enrolled_via=usb
|
|
DRIVES
|
|
|
|
create_enrolled_yubikeys
|
|
|
|
echo "sk-ssh-ed25519 AAAA key1" > "${TEST_WORK}/ssh-keys/yubikey1_storagenode.pub"
|
|
echo "sk-ssh-ed25519 BBBB key2" > "${TEST_WORK}/ssh-keys/yubikey2_storagenode.pub"
|
|
cat "${TEST_WORK}"/ssh-keys/*.pub > "${TEST_WORK}/authorized_keys"
|
|
|
|
echo "#!/bin/sh" > "${TEST_WORK}/drive-resolver.sh"
|
|
chmod +x "${TEST_WORK}/drive-resolver.sh"
|
|
|
|
cat > "$CFCONF" << 'CF'
|
|
CF_TUNNEL_TOKEN=eyJ...
|
|
RUSTFS_ROOT_USER=admin
|
|
RUSTFS_ROOT_PASSWORD=testpass12345678
|
|
CF
|
|
|
|
# Verify all required files
|
|
local required_files=(
|
|
"drives.conf"
|
|
"drive-resolver.sh"
|
|
"yubikeys.conf"
|
|
"authorized_keys"
|
|
"cloudflare.conf"
|
|
)
|
|
|
|
for f in "${required_files[@]}"; do
|
|
assert [ -f "${TEST_WORK}/${f}" ]
|
|
done
|
|
}
|
|
|
|
# ─── Drive count validation ───
|
|
|
|
@test "exactly 8 DRIVE_ entries required" {
|
|
cat > "$CONF" << 'DRIVES'
|
|
DRIVE_SATA_1=S001|M|W|B|sata|e
|
|
DRIVE_SATA_2=S002|M|W|B|sata|e
|
|
DRIVE_SATA_3=S003|M|W|B|sata|e
|
|
DRIVE_SATA_4=S004|M|W|B|sata|e
|
|
DRIVE_SATA_5=S005|M|W|B|sata|e
|
|
DRIVE_SATA_6=S006|M|W|B|sata|e
|
|
DRIVE_NVME_DOCKER=N001|M|W|B|nvme|e
|
|
DRIVE_HDD_BACKUP=H001|M|W|B|sata|e
|
|
DRIVES
|
|
local total
|
|
total=$(grep -c "^DRIVE_" "$CONF")
|
|
assert_equal "$total" "8"
|
|
}
|
|
|
|
# ─── Log integrity ───
|
|
|
|
@test "log records all state transitions with timestamps" {
|
|
state_mark "phase1_init"
|
|
state_mark "drive_sata_1"
|
|
state_mark "cf_tunnel"
|
|
|
|
run grep -c "STATE:.*completed" "$LOG"
|
|
assert_output "3"
|
|
|
|
# Verify timestamp format
|
|
run grep -P "^\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\]" "$LOG"
|
|
assert_success
|
|
}
|
|
|
|
@test "log is append-only across resume" {
|
|
state_mark "drive_sata_1"
|
|
local lines_before
|
|
lines_before=$(wc -l < "$LOG")
|
|
|
|
# Simulate resume
|
|
source_nanny_functions
|
|
state_mark "drive_sata_2"
|
|
|
|
local lines_after
|
|
lines_after=$(wc -l < "$LOG")
|
|
assert [ "$lines_after" -gt "$lines_before" ]
|
|
|
|
# Original entry still present
|
|
run grep "drive_sata_1 completed" "$LOG"
|
|
assert_success
|
|
}
|
|
|
|
# ─── Edge cases ───
|
|
|
|
@test "state file with trailing newline works" {
|
|
printf "drive_sata_1\n\n" > "$STATE"
|
|
run state_done "drive_sata_1"
|
|
assert_success
|
|
}
|
|
|
|
@test "state file with windows line endings still works" {
|
|
printf "drive_sata_1\r\n" > "$STATE"
|
|
# grep -x won't match with \r, but our state should handle it
|
|
# This test documents the limitation
|
|
run grep "drive_sata_1" "$STATE"
|
|
assert_success
|
|
}
|
|
|
|
@test "concurrent state writes don't corrupt" {
|
|
# Simulate rapid sequential writes
|
|
for i in $(seq 1 20); do
|
|
state_mark "step_${i}"
|
|
done
|
|
local count
|
|
count=$(wc -l < "$STATE")
|
|
assert_equal "$count" "20"
|
|
}
|