mirror of
https://github.com/GoodOlClint/PSProxmoxVE.git
synced 2026-08-12 23:26:53 +00:00
f21c7f84b7
- Replace tests/infrastructure/Dockerfile with tests/Dockerfile.test (single multi-stage Dockerfile for both CI and local dev) - CI container-image job now builds from Dockerfile.test target dev-infra - Add ARM support: PowerShell installed via dotnet tool on arm64, APT package on amd64 - Replace tests/dev.sh (bash) with tests/dev.ps1 (PowerShell) for cross-platform support (Windows, macOS, Linux) - Add -DockerHost parameter for running x86 containers on a remote Docker host from ARM Macs (rsyncs repo, uses SSH Docker transport) - Add -NoCleanup switch to keep nested PVE VMs after integration tests - integration command now provisions nested PVE VMs instead of testing against a pre-existing PVE directly - Share /opt/pve-isos host path between CI and local dev (was separate Docker named volume) - Delete tools/Invoke-Tests.ps1 (unused, overlapped with run-integration.sh) - Add .gitignore entries for Terraform state/artifacts - Update all documentation references Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
177 lines
9.4 KiB
Markdown
177 lines
9.4 KiB
Markdown
# Integration Tests
|
|
|
|
This directory contains Pester 5 integration tests for PSProxmoxVE that exercise the module
|
|
against a **real, live Proxmox VE API endpoint**. They are skipped by default and must be
|
|
opted into explicitly.
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
### Dedicated test node — never production
|
|
|
|
Integration tests **create and destroy real resources** (VMs, snapshots, ISO uploads, network
|
|
objects, user accounts). You must use a dedicated PVE test cluster or standalone node running
|
|
Proxmox VE **8.x or 9.x**. Never point these tests at a production cluster.
|
|
|
|
Recommended minimum:
|
|
- Single-node cluster or standalone host
|
|
- At least one storage pool with `images`, `iso`, and `rootdir` content types enabled
|
|
- Network access from the machine running Pester to the PVE API port (default 8006)
|
|
|
|
---
|
|
|
|
## Required API Token
|
|
|
|
Create a dedicated API token on the test node with the permissions listed below.
|
|
Using a scoped token (rather than the root password) limits blast radius if credentials leak.
|
|
|
|
```
|
|
pveum user add pester@pve
|
|
pveum acl modify / --users pester@pve --roles PVEAdmin
|
|
pveum user token add pester@pve pester-ci
|
|
```
|
|
|
|
### Minimum permissions per domain
|
|
|
|
| Test area | Required privilege(s) |
|
|
|----------------|----------------------------------------------------------------|
|
|
| Connection | `Sys.Audit` |
|
|
| Nodes | `Sys.Audit` |
|
|
| VMs (read) | `VM.Audit` |
|
|
| VMs (create) | `VM.Allocate`, `VM.Config.Disk`, `VM.Config.Memory`, `VM.Config.Network` |
|
|
| VMs (delete) | `VM.Allocate` |
|
|
| VMs (power) | `VM.PowerMgmt` |
|
|
| VMs (clone) | `VM.Clone` |
|
|
| Storage (read) | `Datastore.Audit` |
|
|
| Storage (ISO) | `Datastore.AllocateSpace`, `Datastore.AllocateTemplate` |
|
|
| Snapshots | `VM.Snapshot`, `VM.Snapshot.Rollback` |
|
|
| Network | `Sys.Modify` |
|
|
| Users | `User.Modify` |
|
|
| Templates | `VM.Allocate`, `VM.Clone` |
|
|
| Cloud-Init | `VM.Config.CloudInit` |
|
|
|
|
---
|
|
|
|
## Environment Variables
|
|
|
|
Set these before running the integration suite. The first six are required; any missing
|
|
required variable causes every integration test to be skipped with a clear reason message.
|
|
|
|
| Variable | Required | Description | Example value |
|
|
|--------------------------|----------|-----------------------------------------------------------------------|-----------------------------------------------------|
|
|
| `PVETEST_HOST` | Yes | Hostname or IP address of the test PVE node | `192.168.1.10` or `pve-test.internal` |
|
|
| `PVETEST_PORT` | Yes | PVE API port | `8006` |
|
|
| `PVETEST_APITOKEN` | Yes | API token in `USER@REALM!TOKENID=UUID` format | `pester@pve!pester-ci=xxxxxxxx-xxxx-xxxx-xxxx-xxxx` |
|
|
| `PVETEST_NODE` | Yes | Node name as it appears in `pvesh get /nodes` | `pve-test1` |
|
|
| `PVETEST_STORAGE` | Yes | Storage pool to use for disk and ISO operations | `local` |
|
|
| `PVETEST_ISO_PATH` | Yes | Local path to a small `.iso` file used for upload tests | `/tmp/tinycorelinux.iso` |
|
|
| `PVETEST_PASSWORD` | No | Root password for cloud-init Linux VM provisioning | *(use a strong password)* |
|
|
| `PVETEST_CLOUD_IMAGE_URL`| No | URL for cloud image download (defaults to Ubuntu Noble) | `https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img` |
|
|
| `PVETEST_PVE_VERSION` | No | Expected PVE major version (8 or 9) | `9` |
|
|
|
|
### Setting variables (Bash / zsh)
|
|
|
|
```bash
|
|
export PVETEST_HOST="192.168.1.10"
|
|
export PVETEST_PORT="8006"
|
|
export PVETEST_APITOKEN="pester@pve!pester-ci=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
export PVETEST_NODE="pve-test1"
|
|
export PVETEST_STORAGE="local"
|
|
export PVETEST_ISO_PATH="/tmp/tinycorelinux.iso"
|
|
# Optional — required for Linux VM provisioning tests
|
|
export PVETEST_PASSWORD="<your-test-password>"
|
|
```
|
|
|
|
### Setting variables (PowerShell)
|
|
|
|
```powershell
|
|
$env:PVETEST_HOST = '192.168.1.10'
|
|
$env:PVETEST_PORT = '8006'
|
|
$env:PVETEST_APITOKEN = 'pester@pve!pester-ci=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
|
$env:PVETEST_NODE = 'pve-test1'
|
|
$env:PVETEST_STORAGE = 'local'
|
|
$env:PVETEST_ISO_PATH = '/tmp/tinycorelinux.iso'
|
|
# Optional — required for Linux VM provisioning tests
|
|
$env:PVETEST_PASSWORD = '<your-test-password>'
|
|
```
|
|
|
|
### GitHub Actions / CI
|
|
|
|
Add the variables as repository **Actions secrets** and expose them as environment variables
|
|
in your workflow:
|
|
|
|
```yaml
|
|
env:
|
|
PVETEST_HOST: ${{ secrets.PVETEST_HOST }}
|
|
PVETEST_PORT: ${{ secrets.PVETEST_PORT }}
|
|
PVETEST_APITOKEN: ${{ secrets.PVETEST_APITOKEN }}
|
|
PVETEST_NODE: ${{ secrets.PVETEST_NODE }}
|
|
PVETEST_STORAGE: ${{ secrets.PVETEST_STORAGE }}
|
|
PVETEST_ISO_PATH: ${{ secrets.PVETEST_ISO_PATH }}
|
|
PVETEST_PASSWORD: ${{ secrets.PVETEST_PASSWORD }}
|
|
```
|
|
|
|
---
|
|
|
|
## How to Run
|
|
|
|
The integration suite is tagged `Integration`. Use the `-Tag` filter so that the unit
|
|
tests and integration tests can be run independently.
|
|
|
|
### Via the dev container (recommended)
|
|
|
|
```powershell
|
|
./tests/dev.ps1 integration
|
|
```
|
|
|
|
### Directly with Invoke-Pester
|
|
|
|
```powershell
|
|
# Run integration tests only
|
|
Invoke-Pester -Path ./tests/PSProxmoxVE.Tests -Tag Integration -Output Detailed
|
|
|
|
# Run everything (unit + integration)
|
|
Invoke-Pester -Path ./tests/PSProxmoxVE.Tests -Output Detailed
|
|
|
|
# Run unit tests only (exclude integration)
|
|
Invoke-Pester -Path ./tests/PSProxmoxVE.Tests -ExcludeTag Integration -Output Detailed
|
|
```
|
|
|
|
---
|
|
|
|
## Warning — Real Resources Are Created and Destroyed
|
|
|
|
The integration tests:
|
|
|
|
- **Create VMs** (named `pester-test-vm`, `pester-clone-vm`, `pester-linux-vm`) on `PVETEST_NODE`
|
|
- **Delete** those VMs after the test completes (via `AfterAll` cleanup)
|
|
- **Provision a Linux VM** with cloud-init, guest agent, and disk import (when `PVETEST_PASSWORD` is set)
|
|
- **Start and stop** VMs, including graceful ACPI shutdown via guest agent
|
|
- **Create and delete a snapshot** on an existing stopped VM
|
|
- **Upload an ISO** to `PVETEST_STORAGE`
|
|
- **Download a cloud image** to PVE storage (when `PVETEST_PASSWORD` is set)
|
|
|
|
The `AfterAll` block performs best-effort cleanup. If the test run is interrupted, leftover
|
|
VMs named `pester-*` may remain on the test node and should be removed manually.
|
|
|
|
**Always confirm you are pointing at the correct, isolated test node before running.**
|
|
|
|
---
|
|
|
|
## Planned Test Coverage
|
|
|
|
| Domain | Current integration tests | Planned additions |
|
|
|----------------|--------------------------------------------------------------------------------|----------------------------------------------------------------|
|
|
| Connection | Connect via API token, detect server version | Connect via credential (ticket auth), session expiry handling |
|
|
| Nodes | List nodes, get node status | Node resource usage metrics |
|
|
| VMs | List, create, delete, start, stop, clone | Migrate, resize disk, Get/Set-PveVmConfig, Move-PveVm |
|
|
| Storage | List, upload ISO | Get-PveStorageContent, Invoke-PveStorageDownload, Remove ISO |
|
|
| Snapshots | Create, list, delete snapshot on stopped VM | Restore snapshot, snapshots on running VM (with vmstate) |
|
|
| Network | List node networks | Create bridge, Set-PveNetwork, Invoke-PveNetworkApply |
|
|
| SDN | _(none yet — requires SDN plugin enabled on test node)_ | Get/New/Remove zone and vnet |
|
|
| Users | List users, verify root@pam present | Create/remove user, assign role, set permission |
|
|
| Templates | List templates (count not asserted) | Convert VM to template, deploy VM from template |
|
|
| Cloud-Init | Get cloud-init config from a stopped VM (no-throw assertion) | Set cloud-init fields, verify propagation via VM config |
|
|
| Tasks | _(implicitly exercised via -Wait on lifecycle cmdlets)_ | Get-PveTask, Wait-PveTask with custom timeout |
|