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
+13 -7
View File
@@ -1196,15 +1196,20 @@ func TestCreate_concurrentSameNameSerialised(t *testing.T) {
release := fx.fake.blockOn("Clone")
ids := make([]string, 2)
errs := make([]error, 2)
first := make(chan struct{})
var wg sync.WaitGroup
for i := range ids {
wg.Go(func() { ids[i], errs[i] = fx.p.Create(fx.ctx, fx.req()) })
if i == 0 {
for fx.fake.callCount("Clone") == 0 {
time.Sleep(time.Millisecond)
}
wg.Go(func() {
defer close(first)
ids[0], errs[0] = fx.p.Create(fx.ctx, fx.req())
})
for fx.fake.callCount("Clone") == 0 {
select {
case <-first:
t.Fatalf("first Create returned %v without cloning", errs[0])
case <-time.After(time.Millisecond):
}
}
wg.Go(func() { ids[1], errs[1] = fx.p.Create(fx.ctx, fx.req()) })
close(release)
wg.Wait()
for i, err := range errs {
@@ -1233,7 +1238,8 @@ func TestCreate_cancelledMidWaitReturnsPromptly(t *testing.T) {
return nil
})
start := time.Now()
_, err := fx.p.Create(ctx, fx.req())
var err error
within(t, 10*time.Second, func() { _, err = fx.p.Create(ctx, fx.req()) })
if elapsed := time.Since(start); elapsed > 5*time.Second {
t.Errorf("Create took %v after cancellation", elapsed)
}