doc: промпт Соннету — интеграция polygon ↔ app-autotest
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
# Консультация: интеграция polygon ↔ app-autotest
|
||||
|
||||
> Адресат: Claude Sonnet 4.6 (новый чат)
|
||||
> Дата: 2026-07-31
|
||||
> ⛔ ОТВЕТ — ТОЛЬКО В ЧАТ. Не редактировать файлы.
|
||||
|
||||
---
|
||||
|
||||
## Контекст
|
||||
|
||||
**Polygon** (v0.2.4) — эмулятор Nubes API. Задеплоен на `polygon.pythonk8s.dev.nubes.ru`,
|
||||
17 эндпоинтов с префиксом `/api/v1/svc`, 37 сервисов, все в памяти.
|
||||
Принимает те же запросы что реальный Nubes API: POST /instances → 201 + Location,
|
||||
POST /instanceOperations → 201 + Location, GET /instanceOperations/default/{id} → cfsParams,
|
||||
POST /run → sleep + apply_effect + dtFinish.
|
||||
|
||||
**app-autotest** (v1.2.23) — Flask-приложение для ручного/сценарного тестирования Nubes.
|
||||
Делает реальные HTTP-запросы к Nubes API через `HttpClient` (обёртка над `requests.Session`).
|
||||
Сейчас ходит только в реальные dev/test стенды.
|
||||
|
||||
**Задача:** сделать так чтобы app-autotest мог ходить в polygon вместо реального API.
|
||||
|
||||
## Как app-autotest подключается к API (сейчас)
|
||||
|
||||
Файл `api/auth.py`:
|
||||
|
||||
```python
|
||||
def get_client():
|
||||
token = get_token()
|
||||
endpoint = detect_endpoint(token) or current_app.config["NUBES_API_ENDPOINT"]
|
||||
return HttpClient(endpoint, token)
|
||||
|
||||
def get_stand():
|
||||
token = get_token()
|
||||
endpoint = detect_endpoint(token) or current_app.config["NUBES_API_ENDPOINT"]
|
||||
return stand_name(endpoint)
|
||||
```
|
||||
|
||||
`detect_endpoint(token)` — пробует dev/test стенды, возвращает URL первого ответившего.
|
||||
Хардкод: `["https://lk-api-gateway-dev...", "https://lk-api-gateway-test..."]`.
|
||||
|
||||
`stand_name(endpoint)` — "dev" или "test" по URL.
|
||||
|
||||
`HttpClient(endpoint, token)` — обёртка `requests.Session`:
|
||||
- `get(path)` — GET, `.json()`
|
||||
- `post(path, body)` — POST, извлекает UUID из заголовка `Location`
|
||||
|
||||
## Проблема
|
||||
|
||||
`detect_endpoint(token)` ВСЕГДА находит реальный стенд (токен валиден).
|
||||
До fallback на `NUBES_API_ENDPOINT` дело НЕ доходит.
|
||||
Даже при `NUBES_API_ENDPOINT=http://localhost:5000` app-autotest долбится в облако.
|
||||
|
||||
## Предлагаемое решение
|
||||
|
||||
Добавить проверку localhost в `get_client()` и `get_stand()`:
|
||||
|
||||
```python
|
||||
def _is_localhost(url):
|
||||
return (url or "").startswith(("http://localhost", "http://127.0.0.1"))
|
||||
|
||||
def get_client():
|
||||
token = get_token()
|
||||
endpoint = current_app.config["NUBES_API_ENDPOINT"]
|
||||
if not _is_localhost(endpoint):
|
||||
endpoint = detect_endpoint(token) or endpoint
|
||||
return HttpClient(endpoint, token)
|
||||
|
||||
def get_stand():
|
||||
token = get_token()
|
||||
endpoint = current_app.config["NUBES_API_ENDPOINT"]
|
||||
if _is_localhost(endpoint):
|
||||
return "mock"
|
||||
endpoint = detect_endpoint(token) or endpoint
|
||||
return stand_name(endpoint)
|
||||
```
|
||||
|
||||
Логика:
|
||||
- Если `NUBES_API_ENDPOINT` указывает на localhost → пропустить detect_endpoint, сразу использовать его
|
||||
- `get_stand()` для localhost → "mock" (вместо "?" которое вернёт stand_name для неизвестного URL)
|
||||
- Ноль новых env-переменных, `NUBES_API_ENDPOINT` уже есть в конфиге
|
||||
|
||||
## Вопросы к Соннету
|
||||
|
||||
### Q1. Достаточно ли проверки localhost?
|
||||
|
||||
Сейчас: `startswith(("http://localhost", "http://127.0.0.1"))`.
|
||||
|
||||
Что насчёт:
|
||||
- `https://polygon.pythonk8s.dev.nubes.ru` — удалённый polygon, НЕ localhost. `detect_endpoint` попытается dev/test и упадёт (потому что polygon не вернёт реальный токен-челлендж). Нужна ли более широкая проверка — например «любой не-deck URL»?
|
||||
- IPv6 localhost `[::1]`?
|
||||
- Docker-сети `http://host.docker.internal`?
|
||||
|
||||
### Q2. stand_name для polygon
|
||||
|
||||
Сейчас `stand_name("http://localhost:5000")` вернёт `"?"` потому что там нет "dev"/"test".
|
||||
Мы предлагаем "mock" для localhost. Но что насчёт:
|
||||
- `https://polygon.pythonk8s.dev.nubes.ru` — stand_name вернёт `"?"` потому что в URL нет "dev"/"test". Нужно ли добавить "polygon" в stand_name?
|
||||
- Трекер инстансов (`/tmp/instances-{clientId}-{stand}.json`) использует stand для имени файла. "?" или "mock" — ок, но для удалённого polygon тоже будет "?".
|
||||
|
||||
### Q3. HttpClient — нужны ли изменения?
|
||||
|
||||
Polygon отдаёт ровно те же форматы что реальный API:
|
||||
- `Location: ./{uuid}` на POST /instances и POST /instanceOperations
|
||||
- `{"results": [...]}` на GET /instances
|
||||
- `{"svcOperation": {"cfsParams": [...]}}` на GET /instanceOperations/default/{id}
|
||||
- Пустое тело 200 на validate-cfs
|
||||
|
||||
Нужно ли что-то менять в `HttpClient.post()` или `http_client.py`?
|
||||
|
||||
### Q4. Токен для polygon
|
||||
|
||||
Polygon НЕ проверяет токен (все `_mock/*` открыты, основные эндпоинты тоже без auth).
|
||||
app-autotest ВСЕГДА шлёт `Authorization: Bearer <token>` через HttpClient.
|
||||
|
||||
Это ок? Или polygon должен проверять токен (хотя бы непустой)?
|
||||
|
||||
### Q5. Порядок запуска для тестов
|
||||
|
||||
При локальном тестировании:
|
||||
```bash
|
||||
# Терминал 1: polygon
|
||||
cd polygon/site && python app.py # порт 5000
|
||||
|
||||
# Терминал 2: app-autotest → polygon
|
||||
cd app-autotest/site && \
|
||||
NUBES_API_ENDPOINT=http://localhost:5000/api/v1/svc \
|
||||
python app.py # порт 5001 или другой
|
||||
```
|
||||
|
||||
Нет ли коллизий портов? app-autotest по умолчанию на 5000, polygon тоже на 5000.
|
||||
|
||||
### Q6. Альтернативный подход
|
||||
|
||||
Вместо проверки localhost, может лучше:
|
||||
- Новая env-переменная `NUBES_MOCK=1` — явное переключение в режим мока?
|
||||
- Или `NUBES_API_ENDPOINT` как единственный источник, а detect_endpoint вызывать только если endpoint НЕ задан явно?
|
||||
|
||||
Какой подход надёжнее?
|
||||
Reference in New Issue
Block a user