Add scenarios for "FETCH_TRANSACTIONS" testing and improve bank-specific bootstrapping logic in mock server.
This commit is contained in:
parent
31f3b04751
commit
abdd81e771
@ -209,7 +209,7 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
const QString tzName = AdbUtils::getDeviceTimezone(m_deviceId);
|
const QString tzName = AdbUtils::getDeviceTimezone(m_deviceId);
|
||||||
QTimeZone deviceTz(tzName.toUtf8());
|
QTimeZone deviceTz(tzName.toUtf8());
|
||||||
if (!deviceTz.isValid()) deviceTz = QTimeZone("Europe/Moscow");
|
if (!deviceTz.isValid()) deviceTz = QTimeZone("Europe/Moscow");
|
||||||
const int maxScrolls = 8;
|
const int maxScrolls = 30;
|
||||||
const int navBarTop = device.screenHeight - (device.screenHeight / 10);
|
const int navBarTop = device.screenHeight - (device.screenHeight / 10);
|
||||||
|
|
||||||
// Целевая дата в таймзоне устройства для поиска заголовка дня в списке
|
// Целевая дата в таймзоне устройства для поиска заголовка дня в списке
|
||||||
@ -258,6 +258,15 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Ждём пока WebView раскроет accessibility tree (иначе dump пустой)
|
||||||
|
for (int wait = 0; wait < 5; ++wait) {
|
||||||
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
if (xmlScreenParser.findTransactionButtons(1).size() > 0) break;
|
||||||
|
if (hasDateOnScreen()) break;
|
||||||
|
qDebug() << "[FetchTransactions] Waiting for WebView content..." << (wait + 1);
|
||||||
|
QThread::msleep(2000);
|
||||||
|
}
|
||||||
|
|
||||||
bool dateFound = false;
|
bool dateFound = false;
|
||||||
for (int scroll = 0; scroll < maxScrolls; ++scroll) {
|
for (int scroll = 0; scroll < maxScrolls; ++scroll) {
|
||||||
if (QThread::currentThread()->isInterruptionRequested()) {
|
if (QThread::currentThread()->isInterruptionRequested()) {
|
||||||
|
|||||||
@ -130,9 +130,28 @@ python mock_server.py --port 8888
|
|||||||
```
|
```
|
||||||
|
|
||||||
Флаги:
|
Флаги:
|
||||||
|
- `--banks ozon` — генерировать задачи только для указанных банков
|
||||||
|
- `--banks ozon dushanbe_city_bank` — несколько банков через пробел
|
||||||
- `--ft-per-material 3` — сколько FT на материал при бутстрапе (default 3)
|
- `--ft-per-material 3` — сколько FT на материал при бутстрапе (default 3)
|
||||||
- `--seed 42` — фиксированный RNG для воспроизводимости
|
- `--seed 42` — фиксированный RNG для воспроизводимости
|
||||||
|
|
||||||
|
Без `--banks` задачи генерируются для всех активных банков.
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
```bash
|
||||||
|
# Только Ozon
|
||||||
|
./run.sh --banks ozon
|
||||||
|
|
||||||
|
# Только Dushanbe
|
||||||
|
./run.sh --banks dushanbe_city_bank
|
||||||
|
|
||||||
|
# Ozon + Dushanbe, по 2 FT на материал
|
||||||
|
./run.sh --banks ozon dushanbe_city_bank --ft-per-material 2
|
||||||
|
|
||||||
|
# Все банки (по умолчанию)
|
||||||
|
./run.sh
|
||||||
|
```
|
||||||
|
|
||||||
### Терминал 2 — ARC
|
### Терминал 2 — ARC
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -241,8 +260,10 @@ python tests/mock_server/gen_mock_data.py
|
|||||||
# Сгенерировать пул задач
|
# Сгенерировать пул задач
|
||||||
python tests/mock_server/gen_fetch_transactions.py
|
python tests/mock_server/gen_fetch_transactions.py
|
||||||
|
|
||||||
# 6. Запустить мок
|
# 6. Запустить мок (все банки)
|
||||||
cd tests/mock_server && python mock_server.py --port 8888
|
cd tests/mock_server && python mock_server.py --port 8888
|
||||||
|
# или только определённые:
|
||||||
|
# cd tests/mock_server && python mock_server.py --port 8888 --banks ozon
|
||||||
|
|
||||||
# 7. Запустить ARC (в отдельном терминале)
|
# 7. Запустить ARC (в отдельном терминале)
|
||||||
./build/ARC # macOS
|
./build/ARC # macOS
|
||||||
|
|||||||
@ -43,6 +43,7 @@ powershell -ExecutionPolicy Bypass -File setup.ps1
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `-Port` | 8888 | Порт mock-сервера |
|
| `-Port` | 8888 | Порт mock-сервера |
|
||||||
| `-FtPerMaterial` | 3 | FETCH_TRANSACTIONS на материал при бутстрапе (из пула) |
|
| `-FtPerMaterial` | 3 | FETCH_TRANSACTIONS на материал при бутстрапе (из пула) |
|
||||||
|
| `-Banks` | все | Банки через запятую: `ozon`, `dushanbe_city_bank`, `black` |
|
||||||
| `-SkipInstall` | — | Пропустить установку Python/Flask |
|
| `-SkipInstall` | — | Пропустить установку Python/Flask |
|
||||||
| `-GenerateOnly` | — | Только сгенерировать данные, не запускать сервер |
|
| `-GenerateOnly` | — | Только сгенерировать данные, не запускать сервер |
|
||||||
| `-Clean` | — | Также очистить пул транзакций (`scenarios/pool/`) |
|
| `-Clean` | — | Также очистить пул транзакций (`scenarios/pool/`) |
|
||||||
@ -56,6 +57,15 @@ powershell -ExecutionPolicy Bypass -File setup.ps1
|
|||||||
# На другом порту с 5 транзакциями на материал
|
# На другом порту с 5 транзакциями на материал
|
||||||
.\setup.ps1 -Port 9999 -FtPerMaterial 5
|
.\setup.ps1 -Port 9999 -FtPerMaterial 5
|
||||||
|
|
||||||
|
# Только Ozon
|
||||||
|
.\setup.ps1 -Banks ozon
|
||||||
|
|
||||||
|
# Только Dushanbe, по 2 транзакции
|
||||||
|
.\setup.ps1 -Banks dushanbe_city_bank -FtPerMaterial 2
|
||||||
|
|
||||||
|
# Ozon + Dushanbe
|
||||||
|
.\setup.ps1 -Banks ozon,dushanbe_city_bank
|
||||||
|
|
||||||
# Пропустить установку (Python/Flask уже есть)
|
# Пропустить установку (Python/Flask уже есть)
|
||||||
.\setup.ps1 -SkipInstall
|
.\setup.ps1 -SkipInstall
|
||||||
|
|
||||||
|
|||||||
@ -112,6 +112,19 @@ def device_label(name: str) -> str:
|
|||||||
return m.group(1) if m else name
|
return m.group(1) if m else name
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup_events(db_path: Path):
|
||||||
|
"""Delete all events from previous runs."""
|
||||||
|
conn = sqlite3.connect(str(db_path))
|
||||||
|
count = conn.execute("SELECT count(*) FROM events").fetchone()[0]
|
||||||
|
if count > 0:
|
||||||
|
conn.execute("DELETE FROM events")
|
||||||
|
conn.commit()
|
||||||
|
print(f" deleted {count} old events")
|
||||||
|
else:
|
||||||
|
print(" events table clean")
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
def generate(materials: list, out_dir: Path):
|
def generate(materials: list, out_dir: Path):
|
||||||
out_dir.mkdir(parents=True, exist_ok=True)
|
out_dir.mkdir(parents=True, exist_ok=True)
|
||||||
scenarios_dir = out_dir / "scenarios"
|
scenarios_dir = out_dir / "scenarios"
|
||||||
@ -195,6 +208,8 @@ def main():
|
|||||||
db_path = resolve_db_path(config_path)
|
db_path = resolve_db_path(config_path)
|
||||||
print(f"database: {db_path}")
|
print(f"database: {db_path}")
|
||||||
|
|
||||||
|
cleanup_events(db_path)
|
||||||
|
|
||||||
materials = query_active_materials(db_path)
|
materials = query_active_materials(db_path)
|
||||||
if not materials:
|
if not materials:
|
||||||
print("No active materials found in database.", file=sys.stderr)
|
print("No active materials found in database.", file=sys.stderr)
|
||||||
|
|||||||
@ -73,6 +73,7 @@ _device_label_by_material: dict = {} # material_id -> "TECNO KM4" etc.
|
|||||||
_in_flight: set = set() # material_ids with a delivered-but-not-yet-resulted task
|
_in_flight: set = set() # material_ids with a delivered-but-not-yet-resulted task
|
||||||
_bootstrap_done = False
|
_bootstrap_done = False
|
||||||
_bootstrap_ft_count = 3
|
_bootstrap_ft_count = 3
|
||||||
|
_bootstrap_banks: list | None = None # None = all banks
|
||||||
|
|
||||||
|
|
||||||
def ok(data=None):
|
def ok(data=None):
|
||||||
@ -164,6 +165,8 @@ def bootstrap_tasks():
|
|||||||
queued = 0
|
queued = 0
|
||||||
for bp in _bank_profiles:
|
for bp in _bank_profiles:
|
||||||
bank = bp.get("bank_name")
|
bank = bp.get("bank_name")
|
||||||
|
if _bootstrap_banks and bank not in _bootstrap_banks:
|
||||||
|
continue
|
||||||
for mat in bp.get("materials", []):
|
for mat in bp.get("materials", []):
|
||||||
mid = mat.get("id")
|
mid = mat.get("id")
|
||||||
if not mid:
|
if not mid:
|
||||||
@ -946,11 +949,16 @@ if __name__ == "__main__":
|
|||||||
parser.add_argument("--port", type=int, default=8888)
|
parser.add_argument("--port", type=int, default=8888)
|
||||||
parser.add_argument("--ft-per-material", type=int, default=3,
|
parser.add_argument("--ft-per-material", type=int, default=3,
|
||||||
help="How many random FETCH_TRANSACTIONS to bootstrap per material")
|
help="How many random FETCH_TRANSACTIONS to bootstrap per material")
|
||||||
|
parser.add_argument("--banks", nargs="+", default=None,
|
||||||
|
help="Only bootstrap tasks for these banks (e.g. --banks ozon dushanbe_city_bank)")
|
||||||
parser.add_argument("--seed", type=int, default=None,
|
parser.add_argument("--seed", type=int, default=None,
|
||||||
help="RNG seed for reproducible bootstrap picks")
|
help="RNG seed for reproducible bootstrap picks")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
_bootstrap_ft_count = args.ft_per_material
|
_bootstrap_ft_count = args.ft_per_material
|
||||||
|
_bootstrap_banks = args.banks
|
||||||
|
if _bootstrap_banks:
|
||||||
|
print(f"[mock] bootstrap limited to banks: {_bootstrap_banks}")
|
||||||
if args.seed is not None:
|
if args.seed is not None:
|
||||||
random.seed(args.seed)
|
random.seed(args.seed)
|
||||||
|
|
||||||
|
|||||||
@ -2,4 +2,18 @@
|
|||||||
# Start the mock ARC backend. Requires `flask` in the active Python env.
|
# Start the mock ARC backend. Requires `flask` in the active Python env.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
# Find config.ini (project root is two levels up)
|
||||||
|
PROJECT_ROOT="$(cd ../.. && pwd)"
|
||||||
|
CONFIG=""
|
||||||
|
for c in "$PROJECT_ROOT/config.ini" "$PROJECT_ROOT/build/config.ini" "$PROJECT_ROOT/build/Release/config.ini"; do
|
||||||
|
if [ -f "$c" ]; then CONFIG="$c"; break; fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$CONFIG" ]; then
|
||||||
|
echo "[run.sh] generating mock data + cleaning events..."
|
||||||
|
python3 gen_mock_data.py --config "$CONFIG"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
exec python3 mock_server.py --host 127.0.0.1 --port 8888 "$@"
|
exec python3 mock_server.py --host 127.0.0.1 --port 8888 "$@"
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "dushanbe_city_bank",
|
||||||
|
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -100,
|
||||||
|
"created_at": "2026-04-10T09:39:15Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_dushanbe_01_embedded_minus_1"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "dushanbe_city_bank",
|
||||||
|
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -100,
|
||||||
|
"created_at": "2026-04-05T14:31:21Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_dushanbe_02_minus_1_2131"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "dushanbe_city_bank",
|
||||||
|
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -100,
|
||||||
|
"created_at": "2026-04-05T14:25:48Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_dushanbe_03_minus_1_2125"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "dushanbe_city_bank",
|
||||||
|
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -100,
|
||||||
|
"created_at": "2026-04-05T11:36:06Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_dushanbe_04_minus_1_1836"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "dushanbe_city_bank",
|
||||||
|
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -100,
|
||||||
|
"created_at": "2026-04-05T11:19:43Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_dushanbe_05_minus_1_1819"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "dushanbe_city_bank",
|
||||||
|
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 100,
|
||||||
|
"created_at": "2026-04-03T13:52:06Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_dushanbe_06_plus_1_2052"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 10000,
|
||||||
|
"created_at": "2026-04-11T10:39:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_ozon_01_evgeny_plus_100"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -10000,
|
||||||
|
"created_at": "2026-04-10T09:40:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_ozon_02_vlad_minus_100"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -30000,
|
||||||
|
"created_at": "2026-04-08T08:34:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_ozon_03_vlad_minus_300"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 10000,
|
||||||
|
"created_at": "2026-04-08T08:14:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_ozon_04_vlad_plus_100"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 10000,
|
||||||
|
"created_at": "2026-04-08T08:02:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_ozon_05_vlad_plus_100_b"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 10000,
|
||||||
|
"created_at": "2026-04-06T13:54:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "pixel7_ozon_06_evgeny_plus_100_b"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 10000,
|
||||||
|
"created_at": "2026-04-10T09:40:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "tecno_ozon_01_galina_plus_100"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 30000,
|
||||||
|
"created_at": "2026-04-08T08:34:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "tecno_ozon_02_galina_plus_300"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -10000,
|
||||||
|
"created_at": "2026-04-08T08:32:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "tecno_ozon_03_vlad_minus_100_a"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -10000,
|
||||||
|
"created_at": "2026-04-08T08:23:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "tecno_ozon_04_vlad_minus_100_b"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -10000,
|
||||||
|
"created_at": "2026-04-08T08:14:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "tecno_ozon_05_galina_minus_100_a"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": -10000,
|
||||||
|
"created_at": "2026-04-08T08:02:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "tecno_ozon_06_galina_minus_100_b"
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"bank_name": "ozon",
|
||||||
|
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
|
||||||
|
"type": "FETCH_TRANSACTIONS",
|
||||||
|
"body": {
|
||||||
|
"amount": 55000,
|
||||||
|
"created_at": "2026-03-20T14:36:00Z"
|
||||||
|
},
|
||||||
|
"_tag": "tecno_ozon_07_vlad_plus_550"
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user