Ctrl K
ComunidadGuías…

hack/proxmox-e2e-fixture_test.bats

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bats
# The Proxmox e2e fixture is stand-agnostic through ${COZY_PVE_*} variables that
# hack/e2e-chainsaw/_lib/run-proxmox.sh expands with envsubst. GNU envsubst
# expands ${VAR} and nothing else: a ${VAR:-default} stays in the text as it is,
# set or not, and reaches the apiserver as a string where the schema wants an
# integer. So the defaults live in the script, the fixture carries bare
# variables, and the render refuses to hand out a fixture with one left in it.

load test_helper

REPO_ROOT="$(cd "$(dirname "${BATS_TEST_FILENAME:-$0}")/.." && pwd)"
FIXTURE="$REPO_ROOT/hack/e2e-chainsaw/kubernetes-proxmox/tenant.yaml"
RUNNER="$REPO_ROOT/hack/e2e-chainsaw/_lib/run-proxmox.sh"

@test "the fixture carries no shell-style default that envsubst would leave in place" {
  if grep -qE '\$\{[A-Za-z_]+:[-=?+]' "$FIXTURE"; then echo "FAIL: the fixture must not carry a shell-style default envsubst leaves in place"; false; fi
}

# kubernetes-nodes names its release kubernetes-nodes-<CR name> and refuses one
# that does not start with kubernetes-nodes-<spec.cluster>- (_helpers.tpl), so a
# pool named anything but <cluster>-<pool> fails at helm install and the suite
# only learns it from a Machine that never appears.
@test "the fixture's KubernetesNodes is named <cluster>-<pool>, as kubernetes-nodes requires" {
  doc="$(sed -n '/^kind: KubernetesNodes$/,/^---$/p' "$FIXTURE")"
  name="$(printf '%s\n' "$doc" | sed -n 's/^  name: *//p' | head -n 1 | tr -d '"')"
  cluster="$(printf '%s\n' "$doc" | sed -n 's/^  cluster: *//p' | head -n 1 | tr -d '"')"
  if [ -z "$name" ] || [ -z "$cluster" ]; then echo "FAIL: no KubernetesNodes name or spec.cluster in the fixture"; false; fi
  case "$name" in
    "$cluster"-?*) ;;
    *) echo "FAIL: KubernetesNodes $name must be named $cluster-<pool>"; false ;;
  esac
}

@test "render-tenant expands every variable with the runner's defaults" {
  out="$(COZY_PVE_SSH=x COZY_PROXMOX_STORAGE=teststore "$RUNNER" render-tenant)"
  if printf '%s' "$out" | grep -q '\${'; then echo "FAIL: the rendered tenant must not keep an unexpanded variable"; false; fi
  printf '%s' "$out" | grep -qE '^ +prefix: 24$'
  printf '%s' "$out" | grep -qE '^ +storage: "teststore"$'
  printf '%s' "$out" | grep -qE '^ +bridge: "vmbr50"$'
}

@test "render-tenant honours a stand's own values and keeps prefix an integer" {
  out="$(COZY_PVE_SSH=x COZY_PROXMOX_STORAGE=s COZY_PVE_PREFIX=16 COZY_PVE_BRIDGE=vmbr1 "$RUNNER" render-tenant)"
  printf '%s' "$out" | grep -qE '^ +prefix: 16$'
  printf '%s' "$out" | grep -qE '^ +bridge: "vmbr1"$'
}

@test "render-tenant passes the stand's resource pool through, and none by default" {
  out="$(COZY_PVE_SSH=x COZY_PROXMOX_STORAGE=s COZY_PVE_POOL=tenant-e2e "$RUNNER" render-tenant)"
  printf '%s' "$out" | grep -qE '^ +pool: "tenant-e2e"$'
  out="$(COZY_PVE_SSH=x COZY_PROXMOX_STORAGE=s "$RUNNER" render-tenant)"
  printf '%s' "$out" | grep -qE '^ +pool: ""$'
}

# The PVC probe waits for the disk to leave the storage. A listing that fails
# must fail the check: read as empty, it would report a leaked disk as freed.
# (The bodies stay POSIX sh, so the legacy hack/cozytest.sh translator can still
# run them: no `run`, no [[ ]].)
@test "disk-freed fails when the storage cannot be listed, instead of calling the disk gone" {
  stub="$(mktemp -d)"
  printf '#!/bin/sh\necho "ssh: connect to host pve: Connection refused" >&2\nexit 255\n' > "$stub/ssh"
  chmod +x "$stub/ssh"
  rc=0
  out="$(PATH="$stub:$PATH" COZY_PVE_SSH=root@pve COZY_PROXMOX_STORAGE=main-pool "$RUNNER" disk-freed main-pool:vm-1-pvc-x 2>&1)" || rc=$?
  rm -rf "$stub"
  [ "$rc" -ne 0 ]
  case "$out" in *"cannot list main-pool"*) ;; *) echo "$out" >&2; exit 1 ;; esac
  case "$out" in *"is gone"*) echo "$out" >&2; exit 1 ;; esac
}

@test "disk-freed reports the disk gone once a successful listing no longer shows it" {
  stub="$(mktemp -d)"
  printf '#!/bin/sh\necho "Volid Format Type Size VMID"\necho "main-pool:vm-2-pvc-y raw images 1073741824 2"\n' > "$stub/ssh"
  chmod +x "$stub/ssh"
  out="$(PATH="$stub:$PATH" COZY_PVE_SSH=root@pve COZY_PROXMOX_STORAGE=main-pool "$RUNNER" disk-freed main-pool:vm-1-pvc-x 2>&1)"
  rm -rf "$stub"
  case "$out" in *"is gone from main-pool"*) ;; *) echo "$out" >&2; exit 1 ;; esac
}

# The tenant's super-admin kubeconfig is a credential for the whole tenant, kept
# under RUNNER_TEMP for one run. The workflow sets no path of its own, so these
# cases go through the same RUNNER_TEMP fallback the runner provides, with the
# override cleared.
KUBECONFIG_NAME=proxmox-e2e-tenant.kubeconfig
SUITE="$REPO_ROOT/hack/e2e-chainsaw/kubernetes-proxmox/chainsaw-test.yaml.disabled"

@test "tenant-node writes the tenant kubeconfig without group or other bits under umask 022" {
  work="$(mktemp -d)"
  stub="$(mktemp -d)"
  # The secret read answers a kubeconfig and the first tenant read fails, which
  # ends the check right after the fetch with the file in place.
  cat > "$stub/kubectl" <<'STUB'
#!/bin/sh
case "$*" in *"get secret"*) printf '%s' YXBpVmVyc2lvbjogdjEK; exit 0 ;; esac
exit 1
STUB
  chmod +x "$stub/kubectl"
  rc=0
  (umask 022; PATH="$stub:$PATH" RUNNER_TEMP="$work" COZY_PROXMOX_WORKDIR= COZY_PVE_SSH=x COZY_PROXMOX_STORAGE=s "$RUNNER" tenant-node) >/dev/null 2>&1 || rc=$?
  mode="$(ls -l "$work/$KUBECONFIG_NAME" | cut -c1-10)"
  rm -rf "$work" "$stub"
  [ "$rc" -ne 0 ]
  [ "$mode" = "-rw-------" ] || { echo "FAIL: the tenant kubeconfig was written $mode" >&2; exit 1; }
}

@test "apply-tenant removes a tenant kubeconfig an earlier run left behind" {
  work="$(mktemp -d)"
  stub="$(mktemp -d)"
  printf 'an earlier run\n' > "$work/$KUBECONFIG_NAME"
  printf '#!/bin/sh\ncat >/dev/null\n' > "$stub/kubectl"
  chmod +x "$stub/kubectl"
  PATH="$stub:$PATH" RUNNER_TEMP="$work" COZY_PROXMOX_WORKDIR= COZY_PVE_SSH=x COZY_PROXMOX_STORAGE=s "$RUNNER" apply-tenant
  left=no
  [ ! -e "$work/$KUBECONFIG_NAME" ] || left=yes
  rm -rf "$work" "$stub"
  [ "$left" = no ] || { echo "FAIL: apply-tenant left the earlier run's kubeconfig in place" >&2; exit 1; }
}

@test "the suite's finally removes the tenant kubeconfig, so diagnostics after it prints no tenant section" {
  # keep_tenant exits the finally before its deletes, and the kubeconfig has to
  # be gone on that path as well. Diagnostics reads whatever is at the path, so
  # a file left there would be reported as the next run's tenant.
  work="$(mktemp -d)"
  stub="$(mktemp -d)"
  printf 'this run\n' > "$work/$KUBECONFIG_NAME"
  printf '#!/bin/sh\necho "stub $*"\n' > "$stub/kubectl"
  printf '#!/bin/sh\nexit 0\n' > "$stub/ssh"
  chmod +x "$stub/kubectl" "$stub/ssh"
  finally="$(yq -r '.spec.steps[] | select(.name == "replacement-converges-unattended") | .finally[0].script.content' "$SUITE")"
  [ -n "$finally" ]
  PATH="$stub:$PATH" RUNNER_TEMP="$work" COZY_PROXMOX_WORKDIR= COZY_KEEP_TENANT=true sh -c "$finally" >/dev/null
  out="$(PATH="$stub:$PATH" RUNNER_TEMP="$work" COZY_PROXMOX_WORKDIR= COZY_PVE_SSH=x COZY_PROXMOX_STORAGE=s "$RUNNER" diagnostics 2>&1)"
  left=no
  [ ! -e "$work/$KUBECONFIG_NAME" ] || left=yes
  rm -rf "$work" "$stub"
  [ "$left" = no ] || { echo "FAIL: the suite's finally left the tenant kubeconfig in place" >&2; exit 1; }
  case "$out" in *"tenant nodes and pods"*) echo "$out" >&2; exit 1 ;; esac
}