test: traces réelles du moteur jugées contre le contrat (refoptimizer)
Les 16 lignes de testTracesReplayWithZeroDivergence : chaque requête, et chaque réponse de l'optimiseur rejugée sur sa requête (--trace --semantic). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fc41c4ff40
commit
308444f39d
@ -43,29 +43,16 @@ struct Verdict {
|
||||
* Juge une session (un message JSON-RPC par élément, dans l'ordre) contre \p schema.
|
||||
* \p arguments : options en plus (`--requests-only`, `--semantic`).
|
||||
*/
|
||||
inline Verdict juger(const QList<QJsonObject> &messages, const QString &schema, const QStringList &arguments = {})
|
||||
/*! Lance le validateur avec \p arguments (après `--schema`). */
|
||||
inline Verdict lancer(const QString &schema, const QStringList &arguments)
|
||||
{
|
||||
Verdict v;
|
||||
QTemporaryDir dir;
|
||||
if (!dir.isValid()) {
|
||||
v.sortie = QStringLiteral("répertoire temporaire impossible");
|
||||
return v;
|
||||
}
|
||||
QFile f(dir.filePath(QStringLiteral("session.ndjson")));
|
||||
if (!f.open(QIODevice::WriteOnly)) {
|
||||
v.sortie = QStringLiteral("écriture de la session impossible");
|
||||
return v;
|
||||
}
|
||||
for (const QJsonObject &m : messages)
|
||||
f.write(QJsonDocument(m).toJson(QJsonDocument::Compact) + '\n');
|
||||
f.close();
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
p.start(QStringLiteral("python3"),
|
||||
QStringList{QStringLiteral("-I"), QStringLiteral("-B"),
|
||||
racineSources() + QStringLiteral("/tools/etm-powersync-schema-check"),
|
||||
QStringLiteral("--schema"), schema, QStringLiteral("--ndjson"), f.fileName()}
|
||||
+ arguments);
|
||||
QStringLiteral("--schema"), schema} + arguments);
|
||||
if (!p.waitForFinished(60000)) {
|
||||
p.kill();
|
||||
v.sortie = QStringLiteral("validateur sans réponse en 60 s");
|
||||
@ -79,6 +66,31 @@ inline Verdict juger(const QList<QJsonObject> &messages, const QString &schema,
|
||||
return v;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Juge une session (un message JSON-RPC par élément, dans l'ordre) contre \p schema.
|
||||
* \p arguments : options en plus (`--requests-only`, `--semantic`).
|
||||
*/
|
||||
inline Verdict juger(const QList<QJsonObject> &messages, const QString &schema, const QStringList &arguments = {})
|
||||
{
|
||||
QTemporaryDir dir;
|
||||
QFile f(dir.filePath(QStringLiteral("session.ndjson")));
|
||||
if (!dir.isValid() || !f.open(QIODevice::WriteOnly)) {
|
||||
Verdict v;
|
||||
v.sortie = QStringLiteral("écriture de la session impossible");
|
||||
return v;
|
||||
}
|
||||
for (const QJsonObject &m : messages)
|
||||
f.write(QJsonDocument(m).toJson(QJsonDocument::Compact) + '\n');
|
||||
f.close();
|
||||
return lancer(schema, QStringList{QStringLiteral("--ndjson"), f.fileName()} + arguments);
|
||||
}
|
||||
|
||||
/*! Juge un fichier de traces de décision (annexe D) contre \p schema. */
|
||||
inline Verdict jugerTraces(const QString &trace, const QString &schema, const QStringList &arguments = {})
|
||||
{
|
||||
return lancer(schema, QStringList{QStringLiteral("--trace"), trace} + arguments);
|
||||
}
|
||||
|
||||
/*! Écrit \p octets dans \p dir et rend le chemin : le contrat EMBARQUÉ, passé au validateur. */
|
||||
inline QString ecrireSchema(const QTemporaryDir &dir, const QByteArray &octets)
|
||||
{
|
||||
|
||||
@ -836,6 +836,16 @@ void TestRefOptimizer::testTracesReplayWithZeroDivergence()
|
||||
const QStringList fichiers = QDir(d).entryList({"etm-powersync-optimizer-trace-*.ndjson"}, QDir::Files);
|
||||
QCOMPARE(fichiers.count(), 1);
|
||||
const QString trace = QDir(d).filePath(fichiers.first());
|
||||
// Lot contrat OpenRPC : les traces RÉELLES du moteur — requêtes des 16 cycles, réponses de
|
||||
// l'optimiseur rejugées sur leur requête — sont conformes au contrat embarqué.
|
||||
{
|
||||
QTemporaryDir dir;
|
||||
const Contrat::Verdict v = Contrat::jugerTraces(trace, Contrat::ecrireSchema(dir, OptimizerProtocol::schemaDocumentBytes()),
|
||||
{QStringLiteral("--semantic")});
|
||||
QVERIFY2(v.code == 0, qUtf8Printable(v.sortie.right(4000)));
|
||||
QCOMPARE(v.compte("GetPlan.params"), lignes.count());
|
||||
QCOMPARE(v.compte("GetPlan.result"), surplus.count()); // les lignes à latencyMs : celles de l'optimiseur
|
||||
}
|
||||
|
||||
RefOptimizer neuf;
|
||||
QString erreur;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user