Chrono Mock
LangueFrançais

Tester des dates dans un pipeline

La fenêtre sert à explorer. Voici l'autre moitié : une version en ligne de commande d'environ 2,4 Mo, sans environnement d'exécution à installer, dont le code de sortie est le verdict de couverture et non celui de la cible.

Le code de sortie est le verdict

C'est le choix de conception qui rend l'outil scriptable. Quand une session se termine, le code de sortie répond à « la substitution du temps a-t-elle pris effet », et non à « qu'a renvoyé l'application ». Un pipeline peut donc échouer sur une substitution qui n'a silencieusement pas eu lieu - et c'est l'échec qui mérite de faire échouer, car tout ce qui vient après est un test qui n'a rien prouvé.

Le propre code de sortie de la cible est toujours rapporté, dans les données de session.

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
1erreur d'utilisation - une option ou une expression incorrecte
2la cible n'a pas pu être lancée ou injectée
12la cible a disparu, ce qui évoque une application à instance unique
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
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

Toutes les options des deux commandes, et le même tableau pour le calculateur, sont dans la référence de la ligne de commande.

Exécutions bornées

Un pipeline ne peut pas attendre qu'un humain ferme une application de bureau. --ticks N termine la session après N battements - d'une seconde réelle chacun - et rapporte ce qu'il a trouvé jusque-là. La couverture est de toute façon établie dans les premiers instants du processus, si bien qu'une borne courte suffit généralement.

# Dix secondes, puis arrêt et rapport
chrono run ".\build\test.exe" --preset year-rollover --ticks 10 --report evidence.txt

Sortie machine et preuves

  • --json émet la session sous forme d'enregistrements lisibles par une machine au lieu du rapport pour humains - les mêmes faits, y compris la couverture par canal.
  • --report <path> écrit le rapport pour humains dans un fichier, ce qui fait un artefact de build raisonnable. Une session dont le verdict n'est pas fonctionne place en tête de ce fichier un bandeau de preuve peu fiable, plutôt que d'enfouir la réserve en bas.
  • Le calculateur comprend aussi --json, de sorte qu'un pipeline peut calculer la date dont il a besoin et la réinjecter.
# Calculer la date, puis exécuter à cette date
chrono calc --base today --snap eom --json
chrono run ".\build\test.exe" --preset month-end --ticks 10 --json

Une étape, en gros

- name: Month-end behaviour
  shell: pwsh
  run: |
    .\chrono.exe run ".\build\test.exe" --preset month-end --ticks 10 --report evidence.txt
    # un code de sortie non nul ici signifie que la substitution n'a pas pris, donc le
    # test qui suit n'aurait rien prouvé

- name: Keep the evidence
  uses: actions/upload-artifact@v7
  with:
    name: chrono-evidence
    path: evidence.txt

Deux réserves honnêtes sur les runners

  • Il faut un runner Windows. Il n'existe pas de version Linux ou macOS, et il n'y en aura pas - sous Linux, libfaketime couvre déjà ce besoin.
  • L'antivirus d'un runner hébergé peut bloquer l'injection. Décaler le temps revient à injecter une bibliothèque dans le processus cible, une technique Windows documentée qu'utilisent aussi les logiciels malveillants. Un runner qui la bloque produit un code de sortie qui le dit, plutôt qu'un faux succès - mais c'est à découvrir avant d'en dépendre.

Pour la même raison, la suite de tests de bout en bout de ce projet s'exécute sur de vraies machines et non sur un runner hébergé. Son intégration continue compile et teste unitairement tout, et la substitution elle-même est exercée à la main sur de vraies applications, en 32 bits comme en 64 bits, avant chaque version.

L'essayer