61 lines
2.3 KiB
Python
61 lines
2.3 KiB
Python
|
|
#!/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")
|