test_db_save_run.py (4 теста): INSERT/UPDATE/UPSERT/без БД test_auth.py (9 тестов): URL полигона, get_stand, whitelist, режимы test_scenario_full.py (8 тестов): CRUD + запуск (требует polygon + БД) Итого: 35 тестов (22 старых + 13 новых)
115 lines
4.1 KiB
Python
115 lines
4.1 KiB
Python
"""
|
||
Тесты: save_run — ручной UPSERT (UPDATE -> INSERT).
|
||
"""
|
||
import json
|
||
import db.save_run as sv
|
||
|
||
|
||
class FakeCursor:
|
||
def __init__(self):
|
||
self.executed = []
|
||
self.rowcount = 0 # UPDATE not affected (no existing row)
|
||
|
||
def execute(self, sql, params=None):
|
||
self.executed.append((sql, params))
|
||
|
||
def close(self):
|
||
pass
|
||
|
||
|
||
class FakeConn:
|
||
def __init__(self):
|
||
self.committed = False
|
||
self.rolled_back = False
|
||
self.cursor_obj = FakeCursor()
|
||
|
||
def cursor(self):
|
||
return self.cursor_obj
|
||
|
||
def commit(self):
|
||
self.committed = True
|
||
|
||
def rollback(self):
|
||
self.rolled_back = True
|
||
|
||
|
||
def test_first_call_inserts(monkeypatch):
|
||
"""Первый вызов save_run (op_uid=None) -> INSERT."""
|
||
conn = FakeConn()
|
||
monkeypatch.setattr(sv, "get_conn", lambda: conn)
|
||
put_calls = []
|
||
monkeypatch.setattr(sv, "put_conn", lambda c: put_calls.append(c))
|
||
|
||
sv.save_run("cid", "test", "u@e", 1, "", "create", 18,
|
||
None, "inst-1", "display", "RUNNING", 0, "",
|
||
{}, [], "1.0")
|
||
|
||
sqls = [e[0].strip()[:20] for e in conn.cursor_obj.executed]
|
||
assert any("INSERT INTO runs" in s for s in sqls), f"Expected INSERT, got {sqls}"
|
||
assert conn.committed
|
||
assert len(put_calls) == 1
|
||
|
||
|
||
def test_second_call_updates(monkeypatch):
|
||
"""Второй вызов с тем же op_uid -> UPDATE, не INSERT."""
|
||
conn = FakeConn()
|
||
monkeypatch.setattr(sv, "get_conn", lambda: conn)
|
||
monkeypatch.setattr(sv, "put_conn", lambda c: None)
|
||
|
||
# Первый вызов — INSERT (rowcount=0)
|
||
sv.save_run("cid", "test", "u@e", 1, "svc", "create", 18,
|
||
"op-123", "inst-1", "display", "RUNNING", 0, "",
|
||
{"k": "v"}, [], "1.0")
|
||
|
||
# Второй вызов — UPDATE (теперь строка существует)
|
||
conn.cursor_obj.rowcount = 1
|
||
sv.save_run("cid", "test", "u@e", 1, "svc-final", "create", 18,
|
||
"op-123", "inst-1", "display", "OK", 1.5, "",
|
||
{"k": "v"}, [{"stage": 1}], "1.0",
|
||
instance_meta={"cpu": 2})
|
||
|
||
sqls = [e[0] for e in conn.cursor_obj.executed]
|
||
updates = [s for s in sqls if "UPDATE runs SET" in s]
|
||
inserts = [s for s in sqls if "INSERT INTO runs" in s]
|
||
# Первый вызов: UPDATE (rowcount=0) + INSERT. Второй: UPDATE (rowcount=1).
|
||
assert len(updates) == 2, f"Expected 2 UPDATEs, got {len(updates)}"
|
||
assert len(inserts) == 1, f"Expected 1 INSERT, got {len(inserts)}"
|
||
assert conn.committed
|
||
|
||
|
||
def test_update_with_new_status(monkeypatch):
|
||
"""UPDATE меняет status с RUNNING на OK."""
|
||
conn = FakeConn()
|
||
monkeypatch.setattr(sv, "get_conn", lambda: conn)
|
||
monkeypatch.setattr(sv, "put_conn", lambda c: None)
|
||
|
||
# Первый вызов — INSERT (rowcount=0 по умолчанию)
|
||
sv.save_run("cid", "test", "u@e", 1, "", "create", 18,
|
||
"op-456", "inst-2", "d", "RUNNING", 0, "", {}, [], "1.0")
|
||
|
||
# Второй вызов — UPDATE (rowcount=1)
|
||
conn.cursor_obj.rowcount = 1
|
||
sv.save_run("cid", "test", "u@e", 1, "final-svc", "create", 18,
|
||
"op-456", "inst-2", "d", "OK", 2.0, "err", {}, [{"s": 1}], "1.0",
|
||
instance_meta={"ram": 4})
|
||
|
||
# Найти ПОСЛЕДНИЙ UPDATE-запрос и проверить параметры
|
||
update_params = None
|
||
for sql, params in conn.cursor_obj.executed:
|
||
if "UPDATE runs SET" in sql:
|
||
update_params = params
|
||
assert update_params is not None, "UPDATE not found"
|
||
assert update_params[0] == "OK" # status
|
||
assert update_params[1] == 2.0 # duration
|
||
assert update_params[2] == "err" # error_log
|
||
assert update_params[4] == "final-svc" # svc_name
|
||
assert update_params[6] == "op-456" # op_uid
|
||
|
||
|
||
def test_db_unavailable_skips(monkeypatch):
|
||
"""Без БД save_run не падает."""
|
||
monkeypatch.setattr(sv, "get_conn", lambda: None)
|
||
# Не должно быть исключений
|
||
sv.save_run("cid", "test", "", 1, "", "create", 18,
|
||
"op-x", "inst-x", "d", "OK", 0, "", {}, [], "1.0")
|