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

323 lines
15 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_test` | `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`)
- Открывает БД, читает `bank_profiles` с проверенным PIN-кодом (`pin_code_checked = 'yes'`) и активные `materials`
- Генерирует:
- `tests/mock_server/default_profile.json` — профиль для мока
- `tests/mock_server/scenarios/*_<card>_fetch_profile.json` — по одному на материал (с номером карты в имени)
- Очищает таблицу `events` в БД
Пример вывода:
```
config: config.ini
database: database/app_data.db
deleted 5 old events
wrote default_profile.json (3 bank_profiles)
wrote scenarios/pixel_7_ozon_7919_fetch_profile.json
wrote scenarios/pixel_7_ozon_9865_fetch_profile.json
wrote scenarios/pixel_7_dushanbe_city_bank_3258_fetch_profile.json
wrote scenarios/tecno_km4_ozon_0982_fetch_profile.json
Devices (2):
pixel_7: ozon/7919 (50393cc1…), ozon/9865 (06a1ae15…), dushanbe_city_bank/3258 (36002ac2…)
tecno_km4: ozon/0982 (7e3a7e4e…)
```
Флаги: `--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`
- Показывает меню → выбор материала или `all`
- Проходит по транзакциям на экране:
- **Ozon**: парсит заголовки дат (Сегодня/Вчера/dd месяца), определяет дату каждой транзакции по Y-позиции, тапает для получения времени из деталей, скроллит вниз для следующих
- **Dushanbe**: парсит Выписку, тап в детали, время Dushanbe (UTC+5)
- Дедупликация по `(amount, created_at)` — одинаковые суммы в один день с разным временем сохраняются как отдельные задачи
- Сохраняет `scenarios/pool/*_<card>_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
# macOS — только определённые банки
cd tests/mock_server && ./run.sh --banks ozon
# macOS — только FETCH_TRANSACTIONS (без FETCH_PROFILE)
cd tests/mock_server && ./run.sh --types FETCH_TRANSACTIONS --banks ozon
# macOS — debug режим (auto-reload при изменении кода)
cd tests/mock_server && ./run.sh --banks ozon --debug
# Windows
cd tests\mock_server
python mock_server.py --port 8888
```
Флаги `mock_server.py`:
- `--banks ozon dushanbe_city_bank` — только указанные банки
- `--types FETCH_TRANSACTIONS` — только указанные типы задач
- `--ft-per-material 3` — сколько FT на материал при бутстрапе (default 3)
- `--seed 42` — фиксированный RNG для воспроизводимости
- `--debug` — Flask debug режим (auto-reload, состояние сохраняется между перезагрузками)
При `--debug`:
- Изменения в `.py` файлах применяются автоматически без перезапуска
- Состояние задач сохраняется в `.mock_state.json` и восстанавливается при reload
- Скриншоты сохраняются в `.mock_screenshots/` (переживают reload)
- При **первом** запуске — чистый старт (events в БД очищаются, state сбрасывается)
### Терминал 2 — ARC
```bash
# macOS (из корня проекта!)
./build_test/ARC
# Windows
build\Release\ARC.exe
```
При логине мок автоматически ставит задачи:
- 1 × FETCH_PROFILE на каждый материал (если `--types` не ограничивает)
- 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
```
---
## 5. HTML-отчёт
`http://127.0.0.1:8888/_admin/report/html` — веб-страница с:
- Сводкой: всего / выполнено / ошибки / в очереди
- Группировкой по **устройствам****банкам** (Pixel 7 → ozon, dushanbe_city_bank)
- Для каждой задачи:
- Task JSON и Result JSON (для успешных — свёрнуты, кнопка "Показать JSON")
- Ошибки — развёрнуты сразу с красным бейджем
- Скриншот (если есть) — третья колонка, клик открывает полноэкранный просмотр
- Кнопка "Копировать" на каждом JSON блоке
- Цветовой индикацией: зелёный = completed, красный = error, жёлтый = pending
- Авто-обновлением каждые 2 секунды (состояние свёрнутых/развёрнутых блоков сохраняется)
---
## 6. Скриншоты
Приложение отправляет скриншоты через `POST /monitoring/log` с полем `internal_task_id`.
Мок-сервер:
- Сохраняет PNG на диск в `.mock_screenshots/`
- Привязывает к задаче по `internal_task_id` (точное совпадение с `task_result`)
- Отображает в отчёте как третью колонку рядом с Task/Result JSON
- Клик по скриншоту — полноэкранный просмотр (Escape для закрытия)
---
## 7. Ручной инжект задач
```bash
# Одна задача
curl -X POST http://127.0.0.1:8888/_admin/inject \
-H "Content-Type: application/json" \
--data-binary @scenarios/pixel_7_ozon_7919_fetch_profile.json
# Повторный бутстрап (без перезапуска мока)
curl -X POST http://127.0.0.1:8888/_admin/bootstrap
# Сброс (очистка очереди + результатов + скриншотов)
curl -X POST http://127.0.0.1:8888/_admin/reset
```
---
## 8. Админ-эндпойнты мока
| Метод | Путь | Назначение |
|---|---|---|
| POST | `/_admin/inject` | Положить задачу (или массив) в очередь |
| POST | `/_admin/bootstrap` | Повторный бутстрап |
| 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/screenshot/<id>` | PNG скриншот по ID |
| GET | `/_admin/state` | Счётчики |
| POST | `/_admin/reset` | Очистить всё, сбросить бутстрап |
---
## 9. Полный цикл с нуля
```bash
# 1. Установка
pip install flask
# 2. Собрать ARC, запустить с боевым сервером → залогиниться
# Устройства, профили и материалы появятся в БД
# 3. Переключить config.ini на мок
# [net]
# apiBase=http://127.0.0.1:8888
# 4. Сгенерировать стартовые данные из БД
python3 tests/mock_server/gen_mock_data.py
# 5. Открыть на устройстве банковское приложение → список транзакций
# Сгенерировать пул задач
python3 tests/mock_server/gen_fetch_transactions.py
# 6. Запустить мок
cd tests/mock_server && ./run.sh --banks ozon --debug
# 7. Запустить ARC (из корня проекта, в отдельном терминале)
./build_test/ARC
# 8. Открыть отчёт
open http://127.0.0.1:8888/_admin/report/html
# 9. Дождаться completed = всего в отчёте
# 10. Вернуть config.ini на прод
```
---
## 10. Структура файлов
```
tests/mock_server/
├── mock_server.py # Flask mock-сервер
├── run.sh # запуск (macOS/Linux): gen_mock_data + mock_server
├── gen_mock_data.py # генерация default_profile + scenarios из БД
├── gen_fetch_transactions.py # генерация pool из живого устройства
├── inject.sh # curl-обёртка для инжекта
├── default_profile.json # авто-генерированный профиль для мока
├── README.md # эта инструкция
├── WINDOWS.md # Windows-специфичные нюансы
├── .mock_state.json # состояние задач (debug режим, .gitignore)
├── .mock_screenshots/ # скриншоты с устройств (.gitignore)
├── scenarios/ # FETCH_PROFILE сценарии
│ ├── pixel_7_ozon_7919_fetch_profile.json
│ ├── pixel_7_ozon_9865_fetch_profile.json
│ └── ...
└── scenarios/pool/ # пул FETCH_TRANSACTIONS
├── pixel_7_ozon_7919_01_minus_108_ft_01.json
├── pixel_7_ozon_9865_01_minus_108_ft_01.json
├── pixel_7_dushanbe_city_bank_3258_01_plus_5_ft_01.json
└── ...
```
---
## 11. Типовые проблемы
| Симптом | Причина | Решение |
|---|---|---|
| `config.ini not found` | Скрипт запущен не из корня проекта | `cd` в корень или `--config path` |
| `No active materials` | Нет профилей с проверенным PIN | Запустить ARC с боевым сервером, добавить PIN |
| `No ADB devices match` | Устройства не подключены | `adb devices`, проверить USB |
| `App restarted` ошибки в отчёте | Events остались от прошлого запуска | Мок-сервер чистит events при старте; используйте `run.sh` или запускайте сервер **до** ARC |
| Задача `pending` навсегда | material в `_in_flight` | `/_admin/reset` и перезапустить ARC |
| `Transaction not found` | Баг поиска — скролл, видимость кнопок | Анализировать логи (device= в ошибке) |
| `Page load error` | Ozon WebView не загрузился | Проблема интернета/устройства, таймаут 5 мин |
| Скриншот не привязан | Нет `internal_task_id` | Обновить ARC (фикс в EventHandler.cpp) |
| Pool material_id не совпадает | БД обновилась, pool устарел | Перегенерировать pool или обновить material_id в файлах |
| Порт занят | Другой процесс на 8888 | `--port 9999` + поменять `apiBase` |
---
## 12. Что мок эмулирует и что нет
**Эмулирует:**
- Авторизацию (login/refresh)
- Синхронизацию профилей (current_profile, bank_profile CRUD)
- Выдачу задач (get_tasks) с in-flight контролем
- Приём результатов (task_result) с `internal_task_id`
- Приём скриншотов (monitoring/log) с привязкой к задачам
- Управление устройствами и материалами (toggle)
**Не эмулирует:**
- Валидацию тел запросов
- Webhook-уведомления банков
- Сетевые задержки/таймауты