From bcf9f00654129214920d07c0feb0e86f8ffff4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 31 Jul 2026 18:45:27 +0400 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B0=20=D0=B0=D1=80?= =?UTF-8?q?=D1=85=D0=B8=D1=82=D0=B5=D0=BA=D1=82=D1=83=D1=80=D0=B0=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=BA-=D0=BF=D0=BE=D0=BB=D0=B8=D0=B3=D0=BE=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BE=D1=82=20Opus=20(3=20=D1=84=D0=B0=D0=B7=D1=8B,=2012=20?= =?UTF-8?q?=D1=88=D0=B0=D0=B3=D0=BE=D0=B2,=2010=20=D1=80=D0=B5=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HISTORY/2026-07-31-session.md | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/HISTORY/2026-07-31-session.md b/HISTORY/2026-07-31-session.md index 7d21c53..f6c467a 100644 --- a/HISTORY/2026-07-31-session.md +++ b/HISTORY/2026-07-31-session.md @@ -328,3 +328,76 @@ site/ 1. `mock/nubes_mock.py` — Flask-заглушка (~150 строк) 2. Интеграционный тест: сценарий `create→modify→delete` через `app_client` 3. `NUBES_MOCK=1` в `app.py` для переключения эндпоинта + +--- + +## Архитектура мок-полигона (Опус, 2026-07-31) + +### Принятые решения (10/10) + +| Q | Решение | Обоснование | +|---|---------|-------------| +| Q1 | Отдельный процесс :5001 (A) | `http_client` делает реальные GET/POST — blueprint не проверит | +| Q2 | Папка `polygon/services/*.yaml` | Каждый сервис в своём файле | +| Q3 | Мин. поля (id+код+тип), остальное достраивается | 20+ параметров вручную — ад | +| Q4 | Ленивый dtFinish (A) | Без потоков, детерминированно, `MOCK_OP_DELAY=0.1` | +| Q5 | Единая стейт-машина | create→running→suspended→deleted | +| Q6 | Реальный мерж params | Иначе тест modify→проверить state.params бессмысленен | +| Q7 | Статический stateOut из YAML | Для MVP, генерация потом | +| Q8 | `/_mock/reset` | Без сброса тесты влияют друг на друга | +| Q9 | Тесты через `app_client` | Проверяет реальную связку, не только эмулятор | +| Q10 | refSvcId игнорируем в MVP | validate-cfs всегда OK | + +### Критические точки интеграции (из кода) + +1. **Location обязателен.** `HttpClient.post` достаёт UUID из заголовка `Location`. + Мок ОБЯЗАН отдавать `Location: ./` на POST /instances и POST /instanceOperations. + +2. **Поллинг спит 5с.** `poll_until_done` делает GET, затем `time.sleep(5)`. + При `MOCK_OP_DELAY=0` dtFinish появится на первом же GET — без задержки. + +3. **Точка переключения — auth.py.** `get_client()` → `detect_endpoint()`. + Нужен short-circuit: при `NUBES_MOCK=1` возвращать `http://localhost:5001/api/v1/svc` + и НЕ вызывать `detect_endpoint`. + +4. **validate-cfs = пустое тело.** Мок отдаёт 200 с пустым телом. + +5. **state.params по коду, cfsParams по числовому id.** YAML должен связывать + `svcOperationCfsParamId` ↔ код параметра. + +### План реализации (3 фазы, 12 шагов) + +**Фаза 1 — MVP (create + поллинг):** +1. `polygon/defaults.py` — `default_for(dataType)` по типу +2. `polygon/config_loader.py` — загрузка `services/*.yaml`, достройка defaults +3. `polygon/state.py` — `MockState`: instances, operations, create, run, ленивый dtFinish, reset +4. `polygon/server.py` — Flask, префикс `/api/v1/svc`, Location-заголовки +5. `polygon/services/dummy.yaml` — Болванка (id параметров из HAR) +6. Интеграция в `auth.py`: short-circuit по `NUBES_MOCK` + +**Фаза 2 — полный CRUD + сервисы:** +7. GET /instances/{uid} (state.params/state.out), GET /instances (пагинация) +8. GET /instanceOperations/default/{id}, GET /services, GET /services/{id} +9. `apply_effect`: modify→мерж params, delete→удаление, suspend/resume→статус +10. `/_mock/reset` + `polygon/services/postgresql.yaml` + +**Фаза 3 — тесты:** +11. `tests/conftest.py` — фикстура поднятия мока + автосброс +12. `tests/test_mock_integration.py` — 5 сценариев через `app_client` + +### Структура файлов + +``` +app-autotest/ +├── site/ +│ ├── api/auth.py # +short-circuit NUBES_MOCK +│ └── ... +└── polygon/ + ├── server.py # Flask-приложение эмулятора + ├── state.py # MockState (в памяти) + ├── config_loader.py # загрузка YAML + достройка defaults + ├── defaults.py # default_for(dataType) + └── services/ + ├── dummy.yaml # Болванка + └── postgresql.yaml # PostgreSQL (stateOut: users, databases) +```