1
0
forked from BRT/arc
arc/tests/mock_server/README.md

317 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Интеграционные тесты задач — mock-сервер
ARC запускается как обычно (реальные Android-устройства через ADB), но
подключается к локальному Flask-моку вместо боевого бэкенда. Мок раздаёт
задачи по одной на material, собирает результаты и показывает отчёт в браузере.
---
## 1. Требования
| Компонент | macOS | Windows |
|---|---|---|
| Python | `brew install python` или встроенный | [python.org](https://python.org), галочка «Add to PATH» |
| Flask | `pip install flask` | `pip install flask` |
| ADB | `brew install android-platform-tools` | Используется из `tools\adb\windows\` |
| ARC | `cmake --build build` | `cmake --build build --config Release` |
| Устройства | `adb devices``device` | `tools\adb\windows\adb.exe devices` |
---
## 2. Генерация тестовых данных из БД
Перед первым запуском (или при смене устройств/аккаунтов) нужно сгенерировать
мок-данные из локальной базы. Скрипты читают `config.ini → [db] dbPath`.
### 2.1 Стартовые данные: профиль + FETCH_PROFILE
```bash
# macOS (из корня проекта)
python3 tests/mock_server/gen_mock_data.py
# Windows
python tests\mock_server\gen_mock_data.py
```
Скрипт:
- Находит `config.ini` в текущей директории (или `build/Release/config.ini`)
- Открывает БД, читает активные `devices → bank_profiles → materials`
- Генерирует:
- `tests/mock_server/default_profile.json` — профиль для мока
- `tests/mock_server/scenarios/*_fetch_profile.json` — по одному на материал
- `tests/mock_server/scenarios/*_fetch_transactions.json` — для ручных прогонов
Пример вывода:
```
config: config.ini
database: database/app_data.db
wrote default_profile.json (3 bank_profiles)
wrote scenarios/pixel_7_ozon_fetch_profile.json
wrote scenarios/pixel_7_dushanbe_city_bank_fetch_profile.json
wrote scenarios/tecno_km4_ozon_fetch_profile.json
Devices (2):
pixel_7: ozon (30bc106c…), dushanbe_city_bank (61d967d1…)
tecno_km4: ozon (49001bb5…)
```
Флаги: `--config C:\path\to\config.ini` — если config не в текущей директории.
### 2.2 Пул FETCH_TRANSACTIONS с живого устройства
```bash
# macOS
python3 tests/mock_server/gen_fetch_transactions.py
# Windows
python tests\mock_server\gen_fetch_transactions.py
```
Скрипт:
- Читает БД → находит активные материалы
- Находит подключённые ADB-устройства → матчит по `adb_serial`
- Показывает меню:
```
Available materials (3):
1. Pixel 7 / ozon / Галина Терехина (material 30bc106c…)
2. Pixel 7 / dushanbe_city_bank / Мехрубон (material 61d967d1…)
3. TECNO KM4 / ozon / Владислав Касаткин (material 49001bb5…)
Pick [1-3] or 'all':
```
- После выбора просит открыть список транзакций на устройстве → Enter
- Проходит по каждой транзакции: тап → дамп деталей → назад
(перед каждым тапом проверяет, что мы на списке)
- Сохраняет `scenarios/pool/*_ft_*.json` с реальными `amount` (в копейках)
и `created_at` (UTC, из таймзоны устройства)
- Если мок запущен — сразу инжектит задачи
Флаги:
- `--serial 148697059H000712` — явный ADB-серийник
- `--kopecks 100` — множитель суммы (по умолчанию 100)
- `--config path` — путь к config.ini
---
## 3. Переключение ARC на мок
В `config.ini``[net]`:
```ini
[net]
apiBase=http://127.0.0.1:8888
```
Остальные `path*` оставить как есть.
> На Windows: `config.ini` обычно лежит рядом с `ARC.exe` в `build\Release\`.
> Совет: держите копию `config.ini.mock` и `config.ini.prod`.
---
## 4. Запуск теста
### Терминал 1 — mock-сервер
```bash
# macOS
cd tests/mock_server && ./run.sh
# Windows
cd tests\mock_server
python mock_server.py --port 8888
```
Логи в консоли:
```
[mock] state cleared — starting fresh
[mock] loaded default_profile.json: 3 bank_profiles, 3 materials
[mock] loaded pool: 19 FETCH_TRANSACTIONS across 3 materials
* Running on http://127.0.0.1:8888
```
Флаги:
- `--ft-per-material 3` — сколько FT на материал при бутстрапе (default 3)
- `--seed 42` — фиксированный RNG для воспроизводимости
### Терминал 2 — ARC
```bash
# macOS
./build/ARC
# Windows
build\Release\ARC.exe
```
При логине мок автоматически ставит задачи:
- 1 × FETCH_PROFILE на каждый материал
- N × FETCH_TRANSACTIONS (случайные из pool)
Задачи раздаются **по 1 на material за поллинг** — следующая только после
получения результата предыдущей. Это предотвращает expire задач в очереди.
### Терминал 3 — отчёт
```bash
# Браузер с авто-обновлением (задачи группируются по устройствам)
open http://127.0.0.1:8888/_admin/report/html # macOS
start http://127.0.0.1:8888/_admin/report/html # Windows
# Счётчики в реальном времени
watch -n 2 'curl -s http://127.0.0.1:8888/_admin/state' # macOS
# Windows (PowerShell)
while ($true) { cls; (iwr http://127.0.0.1:8888/_admin/state).Content; sleep 2 }
```
---
## 5. HTML-отчёт
`http://127.0.0.1:8888/_admin/report/html` — веб-страница с:
- Сводкой: всего / выполнено / в очереди
- Группировкой по устройствам (Pixel 7, TECNO KM4, …)
- Для каждой задачи: Task JSON слева ↔ Result JSON справа
- Цветовой индикацией: зелёный = completed, жёлтый = pending, красный = error
- Авто-обновлением каждые 2 секунды (без сброса скролла)
Также доступен JSON:
```bash
curl -s http://127.0.0.1:8888/_admin/report | jq # полный
curl -s http://127.0.0.1:8888/_admin/report/pending | jq # только pending
```
---
## 6. Ручной инжект задач
```bash
# Одна задача
./inject.sh scenarios/pixel_7_ozon_fetch_profile.json # macOS
curl -X POST http://127.0.0.1:8888/_admin/inject ^ # Windows
-H "Content-Type: application/json" ^
--data-binary @scenarios\pixel_7_ozon_fetch_profile.json
# N случайных из пула
python inject_random.py --count 5
# Повторный бутстрап (без перезапуска мока)
curl -X POST http://127.0.0.1:8888/_admin/bootstrap
# Сброс (очистка очереди + результатов + in-flight)
curl -X POST http://127.0.0.1:8888/_admin/reset
```
---
## 7. Админ-эндпойнты мока
| Метод | Путь | Назначение |
|---|---|---|
| POST | `/_admin/inject` | Положить задачу (или массив) в очередь |
| POST | `/_admin/bootstrap` | Повторный бутстрап (1 FP + N FT на material) |
| POST | `/_admin/seed_profile` | Подменить ответ `current_profile` |
| POST | `/_admin/seed_devices` | Подменить список устройств |
| GET | `/_admin/report` | JSON: полный отчёт задачи ↔ результаты |
| GET | `/_admin/report/html` | HTML-отчёт с авто-обновлением |
| GET | `/_admin/report/pending` | Только незавершённые задачи |
| GET | `/_admin/report/fragment` | JSON-фрагмент для JS-обновления |
| GET | `/_admin/state` | Счётчики |
| POST | `/_admin/reset` | Очистить всё, сбросить бутстрап |
---
## 8. Полный цикл с нуля (новая машина / новые устройства)
```bash
# 1. Установка
pip install flask
# 2. Собрать ARC, запустить с боевым сервером → залогиниться → устройства,
# банковские профили и материалы появятся в БД
# 3. Переключить config.ini на мок
# [net]
# apiBase=http://127.0.0.1:8888
# 4. Сгенерировать стартовые данные из БД
python tests/mock_server/gen_mock_data.py
# 5. Открыть на устройстве банковское приложение → список транзакций
# Сгенерировать пул задач
python tests/mock_server/gen_fetch_transactions.py
# 6. Запустить мок
cd tests/mock_server && python mock_server.py --port 8888
# 7. Запустить ARC (в отдельном терминале)
./build/ARC # macOS
build\Release\ARC.exe # Windows
# 8. Открыть отчёт
open http://127.0.0.1:8888/_admin/report/html
# 9. Дождаться completed = всего в отчёте
# 10. Вернуть config.ini на прод
# [net]
# apiBase=http://93.183.75.134:8005
```
---
## 9. Структура файлов
```
tests/mock_server/
├── mock_server.py # Flask mock-сервер
├── run.sh # запуск (macOS/Linux)
├── gen_mock_data.py # генерация default_profile + scenarios из БД
├── gen_fetch_transactions.py # генерация pool из живого устройства
├── inject.sh # curl-обёртка для инжекта
├── inject_random.py # рандомный инжект из pool
├── default_profile.json # авто-генерированный профиль для мока
├── seed_profile.example.json # пример ручного засева
├── README.md # эта инструкция
├── WINDOWS.md # Windows-специфичные нюансы
├── scenarios/ # одиночные задачи (FETCH_PROFILE / FT с пустым body)
│ ├── pixel_7_ozon_fetch_profile.json
│ ├── pixel_7_ozon_fetch_transactions.json
│ ├── tecno_km4_ozon_fetch_profile.json
│ └── ...
├── scenarios/pool/ # пул FETCH_TRANSACTIONS с реальными amount + created_at
│ ├── pixel7_ozon_ft_01_evgeny_plus_100.json
│ ├── tecno_km4_ozon_ft_01_galina_plus_100.json
│ └── ...
└── fixtures/ # XML/PNG дампы экранов (справочно)
├── tecno_ozon/
├── pixel7_ozon/
└── pixel7_dushanbe/
```
---
## 10. Типовые проблемы
| Симптом | Причина | Решение |
|---|---|---|
| `config.ini not found` | Скрипт запущен не из корня проекта | `cd` в корень или `--config path` |
| `No active materials` | БД пустая или профили не active | Запустить ARC с боевым сервером, залогиниться |
| `No ADB devices match` | Устройства не подключены или serial не совпадает | `adb devices`, проверить USB |
| Задача `pending` навсегда | material в in-flight (результат не пришёл) | `/_admin/reset` и перезапустить ARC |
| `Task expired: waited Ns` | Предыдущая задача выполнялась >5 мин | Мок отдаёт по 1 задаче — это уже фикс; убедиться, что `maxScrolls` разумный |
| `Transaction not found` | Транзакции на устройстве не совпадают с pool | Перегенерировать: `gen_fetch_transactions.py` |
| `Cancelled: replaced` | Норма для FETCH_PROFILE — дедупликация по device+bank | Не баг |
| Мок не получает результат | `sendTaskError` шёл в monitoring вместо task_result | Обновить ARC (фикс в EventHandler.cpp) |
| Кракозябры в консоли (Win) | Кодировка | `chcp 65001` перед запуском |
| Порт занят | Другой процесс на 8888 | `--port 9999` + поменять `apiBase` |
---
## 11. Что мок НЕ эмулирует
- Валидацию тел запросов (всё `{success: true}`)
- Хранение скриншотов
- Webhook-уведомления банков
- Сетевые задержки/таймауты