Le FakeOptimizer (QLocalServer/QTcpServer du processus), waitFor(), settle()
et handshakeResult() quittent testoptimizerclient.cpp pour
tests/auto/common/etm-powersync-fakeoptimizer.h, sans changement de
comportement, afin que la suite socketscheduler (brief 4 T3) les réutilise.
Seul ajout : un répondeur optionnel (`responder`) qui consomme les messages
reçus au lieu de les filer — vide par défaut, la suite optimizerclient ne
l'utilise pas.
optimizerclient : 16 fonctions, 67 passés, 0 échec (inchangé).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OptimizerClient : QLocalSocket ou QTcpSocket, NDJSON, JSON-RPC 2.0, identifiants
croissants sur toute la vie du client, une requête GetPlan en vol au plus (la plus
récente remplace l'attente ; la réponse obsolète est reconnue par son id et ignorée).
Handshake §3 : majeure comparée, capabilities mémorisé (présent ≠ absent), délai de
5 s compté depuis le début de la tentative ; reconnexion au backoff 1 → 60 s, remis
à 1 s après un handshake accepté. GetPlan : 10 s, connexion conservée. Ligne non
JSON, message sans id, id jamais émis, ligne de plus de 1 Mio : erreur comptée,
connexion conservée.
Horloge et réveil injectables (OptimizerClientClock, monotone) : aucune lecture de
l'horloge murale. Token relu à chaque connexion dans settingsPath()/
energy-optimizer.token, jamais journalisé ; writeToken() pose le fichier par
QSaveFile en 0600 (droits posés avant l'écriture du secret). Pas de RPC.
Le client n'est instancié nulle part dans le moteur. Suite légère
nymea-energy-optimizerclient : faux serveurs QLocalServer/QTcpServer, temps simulé,
37 cas ; 17 mutations du client, toutes mordent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>