#!/usr/bin/env python3 """Сверка логов race_game_test.sh: A, B (два круга), C (зашёл в разгар круга 1, участвует в круге 2 и выходит).""" import re, sys, os W = sys.argv[1] logs = {n: open(os.path.join(W, n + ".log"), errors="replace").read().splitlines() for n in "ABC"} ok = True def check(cond, text): global ok print((" ДА " if cond else " НЕТ ") + text) if not cond: ok = False def rounds_of(lines): """Таблицы итогов по кругам: список [ [(место, id, время, ворот)...], ... ]""" res, cur = [], [] for l in lines: m = re.search(r"итог: место (\d+) игрок (-?\d+) время (-?[\d.]+) ворот (\d+)", l) if m: if cur and int(m.group(1)) == 1: res.append(cur); cur = [] cur.append((int(m.group(1)), int(m.group(2)), float(m.group(3)), int(m.group(4)))) elif cur and "фаза -> WAIT" in l: res.append(cur); cur = [] if cur: res.append(cur) return res ra, rb = rounds_of(logs["A"]), rounds_of(logs["B"]) print("Итоговые таблицы A:", ra) print("Итоговые таблицы B:", rb) check(len(ra) == 2 and len(rb) == 2, "оба клиента показали итоги двух кругов (%d и %d)" % (len(ra), len(rb))) for i in range(min(len(ra), len(rb))): check(ra[i] == rb[i], "круг %d: таблица мест одинакова на A и B" % (i + 1)) if ra[i]: times = [r[2] for r in ra[i]] check(len(ra[i]) == 2 and all(t > 0 for t in times) and len(set(times)) == len(times), "круг %d: два финиша с разным временем %s" % (i + 1, times)) check([r[0] for r in ra[i]] == [1, 2] and ra[i][0][2] < ra[i][1][2], "круг %d: места 1 и 2 по возрастанию времени" % (i + 1)) if len(ra) == 2: check(len(ra[1]) == 2, "круг 2: C вышел в разгар и убран из итогов (в таблице %d строк)" % len(ra[1])) # один START на круг starts = sum(1 for n in "ABC" for l in logs[n] if "даю старт" in l) check(starts == 2, "команду START дал один клиент на круг (всего %d за 2 круга)" % starts) for n in "AB": senders = re.findall(r"старт от (\d+): слот (\d+) из (\d+)", "\n".join(logs[n])) print(" старт на %s: %s" % (n, senders)) sa = re.findall(r"старт от (\d+): слот (\d+) из (\d+)", "\n".join(logs["A"])) sb = re.findall(r"старт от (\d+): слот (\d+) из (\d+)", "\n".join(logs["B"])) sc = re.findall(r"старт от (\d+): слот (\d+) из (\d+)", "\n".join(logs["C"])) check(len(sa) == 2 and len(sb) == 2 and [s[0] for s in sa] == [s[0] for s in sb], "A и B приняли одних и тех же отправителей START в обоих кругах") if len(sa) == 2 and len(sb) == 2: check(sa[0][2] == "2" and sa[1][2] == "3", "в круге 1 участвовали 2, в круге 2 — 3 игрока (A: %s)" % [s[2] for s in sa]) check(sorted([sa[1][1], sb[1][1], sc[0][1] if sc else "?"]) == ["0", "1", "2"] and sa[0][1] != sb[0][1], "слоты в кругах различны и подряд") # синхронность старта по unix-времени (фаза RACE) def race_unix(lines): return [float(m.group(1)) for l in lines for m in [re.search(r"ФАЗА RACE, unix=([\d.]+)", l)] if m] ua, ub = race_unix(logs["A"]), race_unix(logs["B"]) print(" unix начала гонки A:", ua, " B:", ub) check(len(ua) == 2 and len(ub) == 2 and all(abs(x - y) < 0.35 for x, y in zip(ua, ub)), "начало гонки на A и B совпадает в пределах 0,35 с: %s" % [round(x - y, 3) for x, y in zip(ua, ub)]) # заморозка fr = [float(m.group(1)) for n in "ABC" for l in logs[n] for m in [re.search(r"ЗАМОРОЗКА: сдвиг за отсчёт ([\d.]+)", l)] if m] check(len(fr) >= 5 and max(fr) < 0.01, "заморозка на отсчёте: смещения %s" % fr) # музыка mus_after = [l for n in "AB" for l in logs[n] if "МУЗЫКА после старта" in l] mus_cd = [l for n in "AB" for l in logs[n] if "МУЗЫКА на отсчёте" in l] check(len(mus_after) >= 4 and all("играет=true" in l for l in mus_after), "музыка играет после старта (%d проверок)" % len(mus_after)) check(len(mus_cd) >= 4 and all("false" in l for l in mus_cd), "на отсчёте музыки нет (%d проверок)" % len(mus_cd)) # возрождение resp = [l for n in "AB" for l in logs[n] if "ВОЗРОЖДЕНИЕ" in l] for l in resp: print(" ", l) check(len(resp) >= 4 and all("-> ВЕРНО" in l for l in resp), "возрождение у ворот лицом по трассе (%d проверок, ошибок нет)" % len(resp)) # C: зритель, потом участник c = "\n".join(logs["C"]) check("ГОНКА_ИДЁТ" in c and "участник=false" in c, "C зашёл в разгар круга 1: «гонка идёт», без зачёта") check("УЧАСТНИК=true" in c, "C участвует в круге 2") check("ВЫХОЖУ из игры" in c, "C вышел в разгар круга 2") for n in "ABC": errs = [l for l in logs[n] if "SCRIPT ERROR" in l or (l.startswith("ERROR") and "still in use at exit" not in l) or "Parse Error" in l] check(not errs, "в логе %s нет ошибок скриптов %s" % (n, errs[:2])) check("ГОТОВО" in "\n".join(logs["A"]) and "ГОТОВО" in "\n".join(logs["B"]), "A и B дошли до конца теста") print("\nПРОВЕРКА ПРОЙДЕНА" if ok else "\nПРОВЕРКА ПРОВАЛЕНА") sys.exit(0 if ok else 1)