proxmox: contract and observability tests, integration test, testing docs

The contract sweep in provider_test.go: every method and Check returns
within a second of a cancel, every wrapErr path carries the configured
name, op and id, the V0/V1/V2 logging tiers and the no-op lines, and a
Get over the real client whose HTTP spans are children of provider.get.
proxmox_integration_test.go (-tags=integration) holds TestProxmox_lifecycle
and TestProxmoxCheck_realHost; both compile and skip without
PROXMOX_TEST_*, and have not run against a host yet. make
test-integration-proxmox runs them. docs/testing.md gains the proxmox,
nocloud and keyedlock rows, the Live Proxmox gaps and the integration
section; spec entry 21's section 11 list is ticked.

Waits that could hang the package under a mutation are bounded: the
concurrent-Create loop and eight direct blocking calls in older tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-23 20:43:00 +00:00
co-authored by Claude Opus 5.5
parent 2f89c1fffb
commit 6e9ef26dcb
11 changed files with 1585 additions and 34 deletions
+7 -2
View File
@@ -110,7 +110,8 @@ func TestWaitTask_table(t *testing.T) {
cancel()
}
start := time.Now()
err := fx.p.waitTask(ctx, fx.p.logger(ctx), upid, budget)
var err error
within(t, 10*time.Second, func() { err = fx.p.waitTask(ctx, fx.p.logger(ctx), upid, budget) })
if elapsed := time.Since(start); elapsed > 5*time.Second {
t.Errorf("waitTask took %v", elapsed)
}
@@ -219,7 +220,11 @@ func TestWaitUnlocked_table(t *testing.T) {
ctx, cancel = context.WithCancel(ctx)
cancel()
}
cfg, err := fx.p.waitUnlocked(ctx, fakeNode, testVMID, budget)
var (
cfg vmConfig
err error
)
within(t, 10*time.Second, func() { cfg, err = fx.p.waitUnlocked(ctx, fakeNode, testVMID, budget) })
if tc.wantErr == nil {
if err != nil || cfg["name"] != testName || cfg["lock"] != tc.wantLock {
t.Errorf("waitUnlocked = %v, %v; want the config with lock %q", cfg, err, tc.wantLock)