Paillasse/portail/tests/Reels/decomposer-ouverture.py

61 lines
2.3 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""Décompose le temps d'ouverture d'un lab déjà admis (étape 13) : où passent
les secondes entre « la page voit l'état actif » et « l'invite login: » ?
Usage (sur le serveur, séance préparée par preparer-parcours.php et élève
déjà admis par parcours-lab.py) :
sudo -u www-data python3 tests/Reels/decomposer-ouverture.py
"""
import json
import os
import re
import time
from concurrent.futures import ThreadPoolExecutor
import requests
import websocket
BASE = os.environ.get("PARCOURS_BASE", "https://syllabuslab.fr")
BASE_WS = re.sub(r"^http", "ws", BASE)
ids = json.load(open("/tmp/parcours-identifiants.json"))
s = requests.Session()
tok = re.search(r'name="_token" value="([^"]+)"', s.get(BASE + "/connexion").text).group(1)
s.post(BASE + "/connexion/eleve", data={"_token": tok, "identifiant": ids["eleve_identifiant"], "code": ids["eleve_code"]})
def chrono(f):
t = time.time()
r = f()
return r, time.time() - t
def jeton(url, csrf):
return s.post(url, headers={"X-CSRF-TOKEN": csrf}).json()["jeton"]
def invite(jeton_console):
ws = websocket.create_connection(f"{BASE_WS}/console/{jeton_console}", timeout=10)
ws.send("\r")
sortie, fin = b"", time.time() + 10
# « login: » sur une VM neuve, « $ » si quelqu'un y est déjà connecté.
while not re.search(rb"login:|\$ ", sortie) and time.time() < fin:
m = ws.recv()
sortie += m if isinstance(m, bytes) else m.encode()
ws.close()
for essai in range(1, 4):
(page, t_page) = chrono(lambda: s.get(f"{BASE}/seances/{ids['seance_id']}/attente-eleve").text)
csrf = re.search(r"'X-CSRF-TOKEN': '([^']+)'", page).group(1)
urls = [re.sub(r"^https?://[^/]+", BASE, u) for u in re.findall(r"fetch\('(http[^']+/console)'", page)]
(jetons_seq, t_seq) = chrono(lambda: [jeton(u, csrf) for u in urls])
with ThreadPoolExecutor(len(urls)) as pool:
(jetons_par, t_par) = chrono(lambda: list(pool.map(lambda u: jeton(u, csrf), urls)))
(_, t_ws) = chrono(lambda: invite(jetons_par[0]))
navigateur = 1.0 + t_page + t_par + t_ws
print(f"essai {essai} : page {t_page:.2f} s | 3 jetons console : séquentiel {t_seq:.2f} s, parallèle {t_par:.2f} s "
f"| WebSocket → login: {t_ws:.2f} s | chemin navigateur (pire attente d'interrogation 1 s) ≈ {navigateur:.2f} s")