# Интеграционные тесты задач — 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-уведомления банков - Сетевые задержки/таймауты