#!/usr/bin/env bash set -u -o pipefail TEST_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "${TEST_ROOT}/tests/testlib.sh" source "${TEST_ROOT}/inc/evacuate-proxmox-node.sh" test_stopped_ha_guest_does_not_block_wait() { LOCAL_NODE=node1 HA_WAIT_SECONDS=0 get_local_guests() { printf '%s\n' \ $'100\x1fqemu\x1fstopped\x1fshutdown-ha-vm\x1f1024' \ $'101\x1fqemu\x1frunning\x1fnon-ha-vm\x1f1024' } get_ha_guest_ids() { printf '%s\n' 100 } wait_for_ha_evacuation } test_running_ha_guest_blocks_wait() { LOCAL_NODE=node1 HA_WAIT_SECONDS=0 get_local_guests() { printf '%s\n' $'100\x1fqemu\x1frunning\x1frunning-ha-vm\x1f1024' } get_ha_guest_ids() { printf '%s\n' 100 } wait_for_ha_evacuation } assert_success "stopped HA guest does not block evacuation wait" \ test_stopped_ha_guest_does_not_block_wait assert_failure "running HA guest still blocks evacuation wait" \ test_running_ha_guest_blocks_wait set_routing_fixture() { MIGRATION_NODES=(node2 node3) NODE_STORAGE_CACHE=() NODE_STORAGE_CACHE[node2]='shared-a,shared-b' NODE_STORAGE_CACHE[node3]='shared-a,shared-c' PREFERRED_TARGET=node2 } set_routing_fixture assert_success "preferred destination is eligible" \ choose_destination shared-a '' 0 assert_equal node2 "$CHOSEN_DESTINATION" "preferred destination selected" set_routing_fixture assert_success "affinity fallback is available" \ choose_destination shared-a node3 1 assert_equal node3 "$CHOSEN_DESTINATION" "affinity destination selected" assert_equal "routed to satisfy HA node-affinity preference" "$CHOSEN_NOTE" \ "affinity routing explanation" set_routing_fixture assert_success "storage fallback is available" \ choose_destination shared-c '' 0 assert_equal node3 "$CHOSEN_DESTINATION" "storage-compatible destination selected" set_routing_fixture assert_failure "strict affinity blocks two noncompliant destinations" \ choose_destination shared-a node4 1 set_routing_fixture MIGRATION_NODES=(node2) assert_success "sole eligible node overrides affinity" \ choose_destination shared-a node4 1 assert_equal node2 "$CHOSEN_DESTINATION" "sole eligible destination selected" assert_equal "only eligible node; HA node-affinity preference overridden" \ "$CHOSEN_NOTE" "sole-node override explanation" TEST_RULES_FILE="$(mktemp /tmp/tapm-ha-rules.XXXXXX)" cleanup_evacuation_tests() { if [[ "$TEST_RULES_FILE" == /tmp/tapm-ha-rules.* ]]; then rm -f -- "$TEST_RULES_FILE" fi } trap cleanup_evacuation_tests EXIT printf '%s\n' \ 'node-affinity: preferred-nodes' \ ' resources vm:210,ct:211' \ ' nodes node3:20,node2:10' \ ' strict 1' >"$TEST_RULES_FILE" HA_RULES_FILE="$TEST_RULES_FILE" assert_equal $'preferred-nodes\x1f1\x1fnode3,node2' \ "$(get_guest_node_affinity qemu 210)" \ "QEMU affinity parsing" assert_equal $'preferred-nodes\x1f1\x1fnode3,node2' \ "$(get_guest_node_affinity lxc 211)" \ "LXC affinity parsing" assert_equal $'none\x1f0\x1f' \ "$(get_guest_node_affinity qemu 999)" \ "guest without affinity" finish_tests