Chrono Mock
LangueFrançais

Référence de la ligne de commande

Toutes les options des deux commandes, les deux tableaux de codes de sortie, et comment lire ce qui revient. La version narrative, avec le raisonnement, est sur la page CLI et CI.

Deux commandes

chrono run lance une application à une autre date et heure. chrono calc calcule une date et dit ce qu'elle a d'intéressant. Elles partagent une même grammaire d'étapes : un décalage écrit pour l'une signifie la même chose dans l'autre.

chrono version répond à une troisième question, beaucoup plus petite : de quelle version il s'agit, lequel des deux cœurs est l'exécutable, et quelle version du protocole il parle. Une ligne sur la sortie standard, qu'un script peut capturer.

chrono license répond à la quatrième : sous quelle licence cette version est distribuée, la clause de non-garantie, et les composants tiers qui y sont liés. Elle indique aussi où se trouvent sur le disque le texte complet de la licence et les mentions des composants tiers, ou reconnaît que la copie que vous exécutez ne les a pas à côté d'elle. --components liste chaque composant inclus avec sa version, au lieu d'un résumé.

chrono presets liste le catalogue de scénarios tel que --preset le lit : chaque scénario du dossier, écrit avec les mots que lit la grammaire du calculateur, et chaque fichier qu'il refuserait, avec la raison. --json écrit chronomock.presets/1 et --dir désigne un autre dossier.

chrono run <target> [options]
chrono calc [options]
chrono version        # chrono 0.4.0 (x64, protocol 1)
chrono license        # GPL-3.0-only, and what is bundled
chrono presets        # le catalogue, tel que --preset le lit
chrono --help          # usage for all of them

chrono run - options

OptionCe qu'elle fait
--at <moment> Le moment de départ, dans le fuseau de la session. Absolu (2038-01-19T03:14:07) ou relatif avec un signe en tête (+1d, -2h). Unités : s m h d w mo q y - m désigne les minutes et mo les mois. Sans cette option, l'horloge de la session démarre à l'heure réelle actuelle, si bien que --mode xN seul fait simplement tourner la cible plus vite.
--zone +HH:MM Le fuseau de la session : celui dans lequel le moment est écrit, et celui que renvoient les appels d'heure locale de la cible. Un décalage fixe, sans heure d'été. Sans cette option, le propre fuseau de l'hôte.
--mode flow|frozen|xN flow s'écoule à vitesse réelle, frozen fige l'horloge, xN la fait avancer N fois plus vite (x60 fait d'une heure une minute, x1440 d'un jour une minute).
--scale-duration Accélérer aussi l'axe du temps écoulé : compteurs de ticks, temps d'interruption, mises en sommeil et minuteurs. Les attentes sur objet sont comptées et gardent leur durée réelle. Désactivé par défaut, parce qu'une horloge murale et un chronomètre sont deux questions différentes. Un minuteur ou un délai réglé sur une date et une heure suit l'horloge de la session avec ou sans cette option.
--scale-qpc Met aussi à l'échelle le compteur haute résolution, où Python 3.13+ monotonic, .NET Stopwatch et Java nanoTime lisent le temps écoulé. Désactivé par défaut : une application qui chronomètre son rendu avec ce compteur peut paraître déformée.
--ticks N Termine la session après N battements, d'une seconde réelle chacun, et rapporte. Sans elle, l'outil reste attaché jusqu'à ce que la cible, et chaque programme qu'elle a lancé qui tourne sur l'horloge de la session, se soient terminés - un lanceur qui se termine aussitôt laisse la session à l'application qu'il a démarrée.
--timeout <s> Abandonne après ce nombre de secondes et se termine avec 6, pour un pipeline qui ne doit pas se bloquer. Indépendamment de cette option, un cœur qui ne dit rien pendant 15 secondes est arrêté et se termine aussi avec 6 - dans les deux cas l'exécution est écourtée, elle ne porte donc aucun verdict.
--args "..." Les arguments de la cible, en une seule chaîne, découpée selon la même règle que Windows - un argument contenant des espaces survit donc. Pour une cible Chromium, --user-data-dir et --remote-debugging-port sont refusés plutôt que remplacés : la session a besoin de son propre profil isolé, et lancer discrètement sur votre vrai profil de navigateur est la seule chose qui ne doit pas arriver.
--cwd <dir> Lance la cible dans ce répertoire. Sans elle, la cible hérite du nôtre, ce que faisait chaque exécution avant l'existence de cette option. Une valeur vide est une erreur d'utilisation et non « aucun répertoire » - absent et vide sont deux choses différentes, et seul l'absent est quelque chose que Windows peut recevoir. Un répertoire qui n'existe pas arrête la session avec target.cwd_missing avant que quoi que ce soit soit lancé, au lieu d'apparaître plus tard comme une cible qui n'a pas voulu démarrer.
--preset <id> Prend le moment et la vitesse dans presets/<id>.json. Exclusive avec --at, --mode et --scale-duration, puisque le scénario est alors l'unique source des deux.
--param id=value Renseigne un paramètre de scénario. Répétable, exige --preset. Uniquement dans run, la date de début d'un essai prend par défaut la propre date de création de l'exécutable cible, de sorte qu'un scénario d'essai compte à partir du jour où l'application a été installée sans que vous ayez à la saisir.
--set-after T:M Au battement T, change la vitesse en M. En cours d'exécution, le multiplicateur vaut au moins 1 - figer en pleine session n'est pas proposé ici.
--jump-after T:moment Au battement T, fait sauter l'horloge à ce moment, absolu ou relatif, dans le fuseau de la session.
--force Conserve la session même quand le verdict d'ouverture dit que la substitution n'a pas pris effet - par défaut la cible est arrêtée à la place, car une session qui n'a rien prouvé est pire que pas de session. Le verdict ne change pas, ni le code de sortie. Cela décide seulement si la cible continue de tourner.
--no-embedded Laisse les pages web à l'intérieur de l'application (WebView2, Qt WebEngine) sur l'horloge réelle et n'ouvre aucun port de débogage. Sans cette option, la session demande à un tel moteur d'ouvrir un port local et met ses pages sur l'horloge de la session par ce biais - tant que le port est ouvert, tout autre programme de cet ordinateur peut l'utiliser pour atteindre ces pages.
--elevated-embedded Pour une application qui s'exécute en tant qu'administrateur, depuis un Chrono Mock qui s'exécute lui aussi en tant qu'administrateur. WebView2 ignore pour une telle application le réglage par lequel la session atteint ses pages, donc la session écrit une valeur dans le registre de la machine (HKLM, nommée d'après le .exe de l'application) pour sa durée et la supprime à la fin. Tant que l'application tourne, tout autre programme de cet ordinateur peut atteindre ses pages par le port, et l'application a des droits d'administrateur. Pas avec --no-embedded.
--keep-background-timers Démarre le moteur web - le navigateur d'une application Chromium ou Electron, ou le moteur à l'intérieur d'une application - avec le ralentissement des minuteurs dans les fenêtres masquées désactivé, afin qu'une fenêtre réduite garde la vitesse de la session. L'application travaille alors aussi à plein régime tant qu'elle est masquée. Une application lancée en administrateur via --elevated-embedded ne la reçoit pas.
--dry-run Affiche ce que serait la session sans rien démarrer : le moment et le fuseau résolus et d'où ils viennent, ce dont un scénario a rempli chaque paramètre, les arguments après découpage, et lequel des deux mécanismes la cible emprunterait. Aucun processus n'est lancé et aucun fichier n'est écrit, y compris celui que nomme --report. Elle se termine avec 0 pour un plan réalisable et 2 pour une cible absente, qui est le code qu'une vraie exécution donne pour le même fait. Un plan ne porte aucun verdict et le dit - seule une vraie session en a un. Avec --json, le plan est donné en données, dont session.elevated_embedded et session.elevated_embedded_value, le nom de fichier d'après lequel la valeur du registre serait nommée quand l'option s'applique à une cible .exe, sinon null. Un nom à cet endroit n'est pas une promesse d'écriture : la session n'écrit la valeur que si Chrono Mock lui-même s'exécute en tant qu'administrateur.
--report <path> Écrit le rapport pour humains dans un fichier. Un verdict autre que fonctionne place en tête de ce fichier un bandeau de preuve peu fiable, car une preuve qui cache son propre doute est pire que pas de preuve. Une session au verdict fonctionne reçoit aussi ce bandeau lorsque l'application n'a lu aucune des horloges que la session remplace, ou lorsqu'il s'agit d'un programme Go, dont l'horloge murale échappe à Chrono Mock. Le fichier nomme aussi l'exécution elle-même : la version, l'heure de départ, la cible, son dossier et les options.
--report-args Avec --report, écrit aussi les arguments de la cible dans ce fichier, mot pour mot. Désactivé par défaut, car un argument peut contenir un mot de passe - le fichier indique alors seulement leur nombre.
--json Émet la session sous forme d'enregistrements lisibles par une machine au lieu du rapport - le même flux que consomme la fenêtre elle-même. La sortie propre d'une application console va sur l'erreur standard, si bien que la sortie standard contient les enregistrements et rien d'autre. Une application encore en cours quand la session se termine continue d'y écrire, de sorte que tout ce qui lit l'erreur standard jusqu'au bout l'attend, et l'exécution le dit.

chrono run - codes de sortie

Le code de sortie est le verdict de la session, pas ce que l'application a renvoyé. Le code de sortie propre de l'application est rapporté séparément, dans le rapport et dans les données de session - la page CLI et CI explique pourquoi c'est ainsi.

CodeSignification
0fonctionne - tout processus qui a lu l'heure a vu l'horloge de la session
10fonctionne partiellement - certains canaux couverts, d'autres non
11ne fonctionne pas - la substitution n'a pas atteint les canaux essentiels
4indéterminé - la couverture n'a pas pu être établie. Un honnête « je ne sais pas », jamais un faux succès
12la cible a disparu juste après l'injection sans rien laisser tourner sur l'horloge de la session, ce qui évoque une application à instance unique qui passe la main à une copie déjà en cours, ou un transfert vers un programme que la session n'a pas pu pénétrer, généralement d'une autre architecture (32/64 bits). Une cible qui lance l'application puis se termine est un lanceur, et la session continue pour l'application
1erreur d'utilisation - une option incorrecte, une expression incorrecte, ou un scénario que cette commande n'accepte pas
2la cible n'a pas pu être lancée ou injectée
3erreur interne - le moteur n'a pas pu démarrer, a rencontré un état inattendu ou s'est arrêté avant de clore la session (quel que soit son propre code de sortie). Une telle exécution ne porte aucun verdict
5l'opération n'est pas intégrée à cette version - par exemple un scénario dont le moment exige un calendrier que run ne sait pas encore charger. Volontairement distinct d'une erreur d'utilisation : vous avez demandé quelque chose qui n'existe pas encore, pas quelque chose d'erroné
6l'exécution a été écourtée - --timeout a expiré, ou le moteur a cessé de répondre pendant 15 secondes et a été arrêté. Ce n'est pas un verdict : la session a été interrompue, elle ne prouve donc rien sur la cible, dans un sens ou dans l'autre
7une autre session est déjà en cours - une seule session à la fois. Il suffit de réessayer une fois qu'elle est terminée
8la session a abouti à un verdict, mais sa preuve n'est pas dans le fichier que désigne --report - le disque était plein, ou un autre programme gardait l'ancien fichier ouvert, qui reste alors tel quel. Le verdict figure toujours dans le rapport qu'affiche la commande

Lire le rapport

Sans --json, la session se termine par un rapport en clair. Chaque ligne est soit un fait que la session a observé, soit absente - rien n'est rempli avec une valeur par défaut plausible.

Chrono Mock - session report
  target:   .\build\test.exe
  verdict:  WORKS - time substitution took effect  (processes: 1)
            every process that read time saw the session clock
  session:  fake clock reached 2038-01-19T03:14:08
            real elapsed 1.3s, fake elapsed 1.3s
  exited:   the target closed itself with code 3
  covered channels (substituted, with call counts, 10 calls in all):
            - pid 21240: GetSystemTimeAsFileTime (5 calls)
            - pid 21240: GetLocalTime (5 calls)
  observed channels (hooked but left real):
            - pid 21240: NtCreateUserProcess (0 calls)
  warnings:
            - the target opened a network connection ...
  • verdict - le verdict de la famille sur le processus parent et chaque processus enfant, avec le nombre de processus. C'est le nombre que porte le code de sortie.
  • exited - le code de sortie propre de l'application, et seulement quand elle s'est fermée d'elle-même. Une exécution bornée par --ticks laisse la cible en cours, une session Chromium est une session que l'outil ferme lui-même, et une session qui n'a jamais démarré n'a pas un tel code - la ligne est alors absente plutôt que de montrer un zéro inventé. Un code de plantage arrive sous forme d'un grand nombre négatif, il reçoit donc aussi sa forme hexadécimale.
  • covered - les canaux que la substitution a atteints, avec le nombre de fois où chacun a réellement été appelé, par processus. Les comptes ne sont jamais additionnés entre processus : l'audit d'un processus ne doit pas emprunter les chiffres d'un autre. Un compteur s'arrête à 1048576 et indique alors au moins ce nombre.
  • observed - les canaux interceptés mais volontairement laissés réels, comme les attentes d'objets et les minuteurs multimédias. Une catégorie à part, pour qu'ils ne soient jamais lus comme substitués.
  • uncovered - les canaux que l'application a demandés et que la session n'a pas couverts. C'est ce qui fait passer un verdict à partiellement.
  • not fully cleaned up - tout ce que le nettoyage n'a pas pu retirer. Absent sur une fin propre, qui est le cas normal.

chrono calc - options

Pas de langage naturel : chaque option est une étape, et l'ordre des options est l'ordre des étapes. Le résultat après chaque étape est affiché, de sorte qu'une mauvaise étape est visible plutôt qu'enfouie.

OptionCe qu'elle fait
--base today|now|<moment> Où commencer, today par défaut. Résolu dans le fuseau de la session. Un jour impossible comme 2025-02-31 est refusé, jamais normalisé discrètement au mois suivant.
--base-utc <moment> Comme --base, mais le départ est un instant en UTC, avec un Z final facultatif, et non une heure murale dans le fuseau de la session.
--shift ±N<unit> Répétable. Le signe est obligatoire. Unités : s m h d w mo q y bd, ou leurs noms complets. m désigne les minutes, mo les mois. Les mois, trimestres et années se replient sur la date du calendrier avec un plafonnement, si bien qu'un mois après le 31 janvier est la fin février, et non un nombre fixe de ticks. bd (jours ouvrés) exige --calendar.
--set-time HH:MM:SSFixe l'heure de la journée sur le résultat courant.
--snap <target> Saute à une limite de période : som eom soq eoq soy eoy (début ou fin de mois, de trimestre, d'année). Un début est le premier jour à 00:00:00, une fin le dernier jour à 23:59:59.
--nearest nbd|pbd Le jour ouvré le plus proche vers l'avant ou vers l'arrière, le jour courant compris quand il en est déjà un. Exige --calendar.
--to-zone +HH:MM Une étape : réexprime le même instant dans un autre décalage fixe. L'instant est préservé, la valeur epoch ne bouge donc pas et seuls les champs civils changent. À ne pas confondre avec --zone.
--zone +HH:MM Le fuseau de la session, utilisé pour résoudre today et now et pour afficher le résultat. Sans cette option, le fuseau de l'hôte.
--calendar us-banking|us-federal|pl Charge un calendrier de jours fériés. Il ajoute jour ouvré et jour férié aux métadonnées et active bd et --nearest. Les deux calendriers américains diffèrent par la façon dont ils observent un jour férié tombant un week-end, ce qui est exactement le genre de décalage d'un jour qu'un test doit trouver. Chaque calendrier répond pour une plage d'années : pl à partir de 2002, us-federal à partir de 1960 et us-banking à partir de 2008. Un pas en jours ouvrés qui atteint un jour antérieur est refusé avec le code 1, et une date antérieure est affichée comme non jugée. Quand les jours fériés d'un calendrier ont été vérifiés par rapport à la loi il y a plus d'un an, un jour postérieur qu'il a jugé porte la marque calendar_outdated, car un jour férié plus récent peut manquer.
--preset <id> --param id=value Un moment nommé issu de presets/<id>.json, avec ses paramètres renseignés. Exclusif avec les options d'étape et avec --analyze, et il se combine avec --calendar, --zone et --format.
--analyze <date> Relit une date collée et dit ce que c'est. Un 04/08 ambigu est montré dans ses deux lectures, américaine et polonaise, plutôt que deviné - cette ambiguïté est une vraie source de faux rapports de bug.
--format <mask> Affiche aussi le résultat dans votre propre masque, pour qu'il corresponde au format de l'application testée : yyyy-MM-dd HH:mm:ss. Les jetons sont sensibles à la casse au sens de .NET et de Java - M est le mois, m la minute.
--json Sortie machine (chronomock.calc/1) pour tout ce qui précède, afin qu'un pipeline puisse calculer une date et la renvoyer directement à chrono run.
# Dernier jour ouvré du trimestre, calendrier bancaire américain
chrono calc --base today --snap eoq --nearest pbd --calendar us-banking

chrono calc - codes de sortie

Un tableau distinct, plus petit : le calculateur n'a pas de verdict de couverture à rapporter.

CodeSignification
0calculé
1erreur d'utilisation - une option incorrecte, une date impossible, un dépassement de plage, ou un fichier de calendrier sans aucun jour ouvré
5l'étape ou l'unité n'est pas intégrée à cette version, ou l'étape exige un calendrier que vous n'avez pas fourni. Distinct d'une erreur d'utilisation à dessein, pour qu'un script puisse distinguer « pas encore » de « incorrect »

Ensuite