# Гибридный lab-набор pulumi для vmware-api-simulator

Гибрид под `pulumi-tests/`:

1. **Layer A (обязателен для «100%»)** — HTTP contract matrix: все `IMPLEMENTED`
   REST `verb+path` × majors **6–9**, плюс синтетический **HEAD** на каждый GET
2. **Layer B (smoke / lifecycle)** — официальный
   [`pulumi-vsphere`](https://www.pulumi.com/registry/packages/vsphere/)
3. Deep REST CRUD (session / folder / tag / content library / VM)
4. SOAP-операции из `/sdk/vimService.wsdl` (без нового SOAP universe)

Одним `pulumi-vsphere` закрыть ~1092 REST `verb×path` нельзя — **100% = HTTP-матрица**
(`coverage probed/declared`, `critical=0`), а не число provider-ресурсов.

## Критерии pass (Layer A)

| Проверка | Правило |
|----------|---------|
| Declared | `methods_for_major(M)` минус session DELETE, плюс `HEAD` на каждый GET |
| Probed | Ровно один auth’d probe на каждый declared (`probed == declared`) |
| Critical | `0` — нет 5xx/501; нет `"stub": true` / пустого тела на inventory-critical GET (major 9) |
| Coverage | `{probed - critical}/{declared}` (aggregate + per major) |
| Verb histogram | Включая `HEAD` |

## Что запускается

| Кейс | Слой | Заметки |
|------|------|---------|
| `PU-INV` … `PU-TAG` | B · pulumi-vsphere | Lifecycle / inventory smoke |
| `PU-REST` | **A · HTTP matrix** | `IMPLEMENTED` × 6–9 + HEAD (smoke: major 9) |
| `PU-CRUD` / `PU-SOAP` | extras | Deep CRUD + существующий SOAP |

## Быстрый старт

```bash
make pulumi-tests          # полный гибрид
make pulumi-tests-smoke    # PU-INV + Layer A major-9
```

Шлюз (в compose): `https://api-gateway`. Хост-алиас: `127.0.0.1:28443`
(не занимает `https://localhost` / `:18443` основного lab — после тестов
`make down`).
Seed: `small`. Артефакты: `rest.coverage_line`, `rest.critical`, `rest.by_verb`.
