Tests¶
Les tests sont des tests Pester 5, dans CI/tests, lancés sur le module
construit.
pwsh -File CI/03_Build.ps1
pwsh -File CI/Get-AdmxSource.ps1 # une fois : les fichiers ADMX de Windows que lisent les tests
$Config = New-PesterConfiguration
$Config.Run.Path = 'CI/tests'
$Config.Output.Verbosity = 'Detailed'
Invoke-Pester -Configuration $Config
| Fichier | Couvre |
|---|---|
PSGPOTools.Model.tests.ps1, GPOToolsUtility.tests.ps1 |
ADMX, ADML, catégories, stratégies |
PSGPOTools.RegistryPol.tests.ps1, PSGPOTools.Setting.tests.ps1 |
Registry.pol, l'état de chaque stratégie du jeu ADMX, rapports de paramètres |
PSGPOTools.AccessControl.tests.ps1 |
descripteurs de sécurité, filtrage de sécurité, ACL SYSVOL |
PSGPOTools.Backup.tests.ps1 |
sauvegardes, comparaison, restauration, notes, écart, corbeille, modèles |
PSGPOTools.Configuration.tests.ps1 |
la configuration du domaine |
PSGPOTools.Hardening.tests.ps1 |
ce que pourrait faire un fichier, un attribut, un outil ou un domaine hostile (durcissement) |
PSGPOTools.Workflow.tests.ps1 |
le workflow d'approbation |
PSGPOTools.Delegation.tests.ps1 |
les droits lus dans l'annuaire |
PSGPOTools.Ldap.tests.ps1 |
LDAP, gPLink, samba-tool, RSAT (simulés), et face à un contrôleur de domaine |
PSGPOTools.PasswordPolicy.tests.ps1 |
les stratégies de mot de passe affinées : les valeurs de l'annuaire, les vérifications, le PSO qui s'applique et pourquoi, les commandes |
PSGPOTools.Gui.tests.ps1 |
les vraies fenêtres des deux consoles (-OnShown), une erreur qu'aucun gestionnaire n'a traitée |
PSGPOTools.WindowCode.tests.ps1 |
le code de la console GPO lu comme arbre syntaxique : chaque variable lue est affectée ou un contrôle de son XAML |
PSGPOTools.Health.tests.ps1 |
la santé des GPO et leur réplication entre contrôleurs de domaine (trois simulés) |
PSGPOTools.Posture.tests.ps1 |
la posture de sécurité : les droits trop larges dans l'annuaire et dans SYSVOL, le Tier 0 et ses groupes, les constats dans le journal du système |
PSGPOTools.Inheritance.tests.ps1 |
les liens d'un domaine ou d'une OU par ordre de lien, et les GPO qui s'y appliquent par priorité (Get-PSGPOInheritance) |
PSGPOTools.AvaloniaInstall.tests.ps1 |
le runtime Avalonia : ses paquets et fichiers épinglés, d'où ils viennent, les vérifications avant son chargement |
PSGPOTools.WellKnownSid.tests.ps1 |
les comptes bien connus : leur table, les noms saisis en anglais ou en français, les suggestions pendant la frappe et la complétion des commandes |
PSGPOTools.Release.tests.ps1 |
la construction reproductible, le paquet d'une release (SHA256SUMS, signature, catalogue), les règles des workflows |
PSGPOTools.Public.tests.ps1 |
les commandes exportées |
PSGPOTools.Update.tests.ps1 |
les versions de HGPM et Test-PSGPOUpdate (la Gallery simulée) |
Face à un contrôleur de domaine¶
Les tests d'intégration tournent quand on leur donne un contrôleur de domaine, avec un ticket Kerberos d'un administrateur du domaine :
kinit administrator@HARDENBOX.LABO
export PSGPOTOOLS_TEST_LDAP_SERVER=dc.hardenbox.labo # lit le domaine
export PSGPOTOOLS_TEST_LDAP_WRITE=1 # crée, lie, écrit et supprime aussi
pwsh -c 'Invoke-Pester CI/tests'
Avec PSGPOTOOLS_TEST_LDAP_WRITE=1, ils créent une OU et des GPO nommées PSGPOTools test ..., les
lient, écrivent leurs paramètres, en suppriment et en restaurent une, et suppriment tout ce qu'ils
ont créé à la fin, quoi qui ait échoué. Pour les stratégies de mot de passe (Linux, samba-tool),
ils créent un utilisateur, un groupe de sécurité global et un local de domaine, et des PSO nommés
PSO test ... : protégés contre la suppression accidentelle, renommés, appliqués directement et
par les groupes, une modification faite entre-temps refusée, le PSO trouvé par la console comparé à
msDS-ResultantPSO ; puis ils les suppriment.
Avec aussi PSGPOTOOLS_TEST_LAB_SCRIPTS=1 (Linux), ils lancent les scripts Linux du
labo, New-PSGPOTierLab.ps1 et Grant-PSGPOTierDelegation.ps1, deux fois
chacun : les OU, groupes et comptes des tiers, le mot de passe du labo (un ticket Kerberos de
tiers1), la délégation des liens et de la création de GPO (le workflow activé pour le test). Ils changent le domaine pour de
bon : le job test-samba de la CI le définit, sur son domaine jetable seulement.
Les écritures d'une approbation (PSGPOTools.Hardening.tests.ps1) sont testées avec des mocks :
leur ordre (SYSVOL, les objets que contient la GPO, puis la GPO), la GPO laissée en attente quand
SYSVOL échoue, les permissions retirées et signalées. Le circuit complet, avec ses deux comptes,
tourne aussi contre le contrôleur de domaine (Approval written to a domain controller), après les
scripts du lab :
tiers1, dans un processus à lui avec son ticket Kerberos, crée une GPO : elle attend, personne ne l'applique ;tiers1y ajoute une permission à lui (Domain Users, contrôle total) ;- l'administrateur l'approuve : Domain Admins est propriétaire de la GPO et de son dossier SYSVOL,
la permission ajoutée par
tiers1et ses propres droits ont disparu (et sont signalés), Authenticated Users l'applique ; tiers1ne peut plus l'écrire ;- une GPO que
tiers1modifie après son examen n'est pas approuvée, et reste en attente.
La configuration du domaine est gardée et réécrite octet pour octet. Sur un lab à vous,
PSGPOTOOLS_TEST_TIER1_CCACHE donne le ticket d'un créateur (FILE:/tmp/krb5cc_tiers1) à la place
du mot de passe du lab.
Ce qu'un job doit lancer¶
CI/Invoke-Tests.ps1 -RequireRun nomme les blocs (Describe, Context, jokers) pour lesquels un
lancement existe : un de leurs tests sauté avec son bloc (un runtime d'Avalonia manquant, une
variable du domaine mal nommée) ou non lancé, ou aucun de leurs tests, fait échouer le lancement. Un
test qui se saute lui-même pour une autre plateforme (-Skip:$IsWindows) non. Chaque lancement écrit
un tableau de ses fichiers (réussis, échoués, sautés, non lancés) dans le résumé de son job sur
GitHub (GITHUB_STEP_SUMMARY).
CI¶
.github/workflows/ci.yml lance quatre jobs à chaque push sur master et main, et à chaque pull
request (avec le seul droit de lire le dépôt ; les actions épinglées à un commit, Pester,
PSScriptAnalyzer et le générateur du site à une version) :
| Job | Lance |
|---|---|
build |
construit le module une fois (CI/03_Build.ps1), vérifie que son manifeste est celui du dépôt, et le donne aux autres jobs (l'artefact module) : ils testent celui-là, et la release le publie |
test |
reconstruit le module sous Windows et vérifie qu'il a les mêmes octets (la construction est reproductible), PSScriptAnalyzer sur Code/ (PSScriptAnalyzerSettings.psd1 : aucune erreur, aucun avertissement), puis tous les tests sur windows-latest ; les fenêtres doivent tourner (-RequireRun) |
test-linux |
tous les tests sur ubuntu-latest (Avalonia sur Xvfb) ; les fenêtres doivent tourner |
test-samba |
les tests qui écrivent dans un domaine, contre un contrôleur Samba AD provisionné sur la machine de la CI (CI.TEST), avec un ticket Kerberos de son administrateur ; la lecture du domaine, les scripts du lab, l'approbation, les modifications et les stratégies de mot de passe doivent tourner |
La page de chaque commande publique (docs/<langue>/reference/commands/, et son entrée dans le menu) est
écrite à partir de son aide par CI/Update-CommandReference.ps1, après CI/03_Build.ps1 ; le premier
.LINK de l'aide d'une commande est sa page, que Get-Help <commande> -Online ouvre. Un test vérifie que
les pages sont celles de l'aide.
Le dépôt ne garde aucun fichier de Microsoft. Les tests lisent les fichiers ADMX de Windows dans
sources/PolicyDefinitions, qui n'est pas dans Git : CI/Get-AdmxSource.ps1 les y installe avec
Install-PSGPOAdmx -AllLanguages, depuis le paquet de Microsoft qu'épingle le module, gardé dans
sources/package (la CI le met en cache). Install-PSGPOAdmx n'installe que le paquet qu'épingle
HGPM/Resources/PolicyDefinitions.json (son adresse, sa taille et son SHA-256), et de lui que les
fichiers épinglés (chaque ensemble, les .admx et chaque langue : son nombre de fichiers et un
SHA-256, la casse des noms mise à part). Pour un nouveau paquet de Microsoft,
CI/Update-AdmxCatalog.ps1 -MsiPath réécrit le catalogue ; un test le vérifie.
.github/workflows/release.yml publie le module sur la PowerShell Gallery pour un tag de version
(v0.1.3-alpha) seulement, jamais pour un commit. Il lance les jobs de la CI sur le commit tagué, puis,
sous Windows, avec les droits dont il a besoin et ceux-là seulement :
CI/04_Publish.ps1vérifie la version (le tag est la version du manifeste,CHANGELOG.mda sa section, la galerie ne l'a pas encore) ;CI/05_Package.ps1fait le paquet à partir du module que les tests ont exécuté (l'artefactmodule, jamais une construction à lui) : signé avec Authenticode, avec son catalogueHGPM.cat, quand les secretsCODE_SIGNING_PFX(le PFX en Base64) etCODE_SIGNING_PASSWORDsont donnés ; son archive, les archives hors ligne avec le runtime Avalonia de chaque plateforme, etSHA256SUMS;actions/attestatteste chaque fichier deSHA256SUMS(gh attestation verify) ;CI/04_Publish.ps1publie le paquet avec le secretPSGALLERY_API_KEY, et la release GitHub est créée avec les notes de la version, les archives etSHA256SUMS.
Les secrets sont ceux de l'environnement psgallery, dont les règles de protection s'appliquent avant
qu'ils soient donnés.
La documentation est construite et publiée par .github/workflows/docs.yml. Il fait la page Historique des
versions à partir de CHANGELOG.md, et met la version du module (ModuleVersion de son manifeste) et le
commit à partir duquel le site est construit en pied de chaque page.