Documentatie
Alles wat de tool doet, geordend als de vragen waarmee mensen echt komen. De README in de repository is de volledige referentie en komt altijd overeen met de build die je hebt gedownload.
Welke opdrachten zijn er?
Elke doet precies één ding:
tfg generate bestanden maken, uit een recept of met opties
tfg validate een recept controleren en niets schrijven
tfg verify een map controleren tegen een manifest
tfg cleanup de bestanden verwijderen die een manifest opsomt
tfg recipe fmt een recept in zijn vaste vorm afdrukken
tfg preset een set bestanden bouwen uit een benoemde testvraag
tfg formats de formaten opsommen die deze build ondersteunt
tfg damage de manieren opsommen waarop deze build een bestand met opzet kan beschadigen
tfg tool kleine hulpmiddelen voor bestanden die je al hebt
tfg version de versie van de tool tonen
tfg license de licentie tonen en wat die betekent voor gegenereerde bestanden
Hoe genereer ik één bestand van een exacte grootte?
Noem het formaat, de grootte en waar het naartoe moet. Groottes tellen in 1024-tallen, dus
2mb is 2097152 bytes. Een gewoon aantal bytes werkt ook, dus --size
10485761 vraagt precies zoveel.
tfg generate --format png --size 2mb --out ./out
De nuttige opties van generate:
| Optie | Wat het doet |
|---|---|
--format <id> | formaat van de bestanden, bijvoorbeeld txt |
--size <size> | exacte grootte van elk bestand, zoals 10mb of een gewoon aantal bytes |
--size-range <a-b> | een grootte die per bestand uit een bereik wordt getrokken, zoals 1kb-8kb. De trekking komt uit de seed |
--boundary <size> | drie bestanden rond een limiet: één byte eronder, de limiet, één byte erboven |
--count <n> | hoeveel bestanden te maken. Standaard 1 |
--name <template> | naamsjabloon, bijvoorbeeld invoice_{index:04}.txt |
--out <dir> | map om naartoe te schrijven |
--seed <n> | seed van de run. Dezelfde seed geeft dezelfde bytes |
--set <k>=<v> | een formaatinstelling, herhaalbaar |
--damage <name> | de bestanden met opzet beschadigen, herhaalbaar en in volgorde toegepast. Draai tfg damage voor de lijst |
--expected <outcome> | accept, reject, sanitize of unspecified |
--dry-run | tellen en tonen, helemaal niets schrijven |
--json | het manifest naar de standaarduitvoer schrijven |
Hoe maak ik een bestand dat met opzet kapot is?
Elk ander bestand dat deze tool schrijft is correct per constructie, wat twee van de drie vragen
beantwoordt die een uploadvalidator stelt. --damage beantwoordt de derde - gaat het
bestand überhaupt open. Het bestand wordt normaal gemaakt en daarna beschadigd, dus het heeft
nog steeds de grootte die je vroeg.
tfg generate --format png --size 2mb --damage zero-head --out ./out
tfg generate --format png --size 2mb --damage zero-head:bytes=16 --out ./out
Instellingen komen na een dubbele punt. De optie herhaalt zich, en de volgorde waarin je ze schrijft
is de volgorde waarin ze worden toegepast. tfg damage toont wat deze build kan en
wat elke variant accepteert.
In een recept is de sleutel een lijst, van namen of van instellingen:
targets:
- id: broken
format: png
count: 5
size: 2mb
damage:
- zero-head
- type: zero-head
bytes: 16
Een beschadigd bestand krijgt expected: reject in het manifest, met de beschadiging
ernaast vastgelegd. Twee dingen worden geweigerd voordat er iets wordt geschreven, omdat elk
anders een bestand op schijf zou zetten dat het manifest verkeerd beschrijft:
- een bestand dat kleiner is dan de beschadiging nodig heeft, omdat het ongewijzigd zou uitkomen
-
expected: acceptnaast een beschadiging, omdat niets daaraan kan voldoen. Schrijfsanitizeals het geteste systeem het bestand moet repareren, ofunspecifiedals dat de vraag is die je stelt
Een derde is vooraf niet te weten. Als een beschadiging draait en geen enkele byte verschuift, wordt dat bestand weggegooid in plaats van geschreven - de run gaat door, zegt om welk bestand het ging en eindigt met de gedeeltelijke afsluitcode.
Stap voor stap, met een test die het manifest leest: hoe maak je een beschadigd bestand om mee te testen.
Hoe ziet een recept eruit?
Een recept is een YAML-bestand dat een hele run beschrijft. Commit het naast je tests en de fixtures zijn geen binaries meer in je repository - iedereen kan ze byte voor byte opnieuw opbouwen uit een bestand van een paar honderd tekens.
# fixtures.yaml
version: 1
seed: 7741
defaults:
label: true
targets:
- id: invoices
format: pdf
count: 25
size: 300kb
name: invoice_{index:04}.pdf
properties:
pages: 3
page_size: a4
expected: accept
- id: over_the_limit
format: png
count: 2
size: 12mb
expected:
outcome: reject
reason: size_limit
- id: bundle
format: zip
contains:
- format: txt
count: 200
size: 4kb
output:
dir: ./fixtures
manifest: manifest.json
tfg validate fixtures.yaml
tfg generate fixtures.yaml
Elk target heeft precies één van deze sleutels nodig: size, size-range,
boundary of contains. Twee is een fout en geen ook. Een ongeldig
recept schrijft helemaal geen bestanden en meldt alle problemen tegelijk in
plaats van alleen het eerste, elk met de instelling waar het over gaat.
Hoe leg ik vast wat mijn systeem met een bestand moet doen?
Korte vorm als de uitkomst genoeg is, lange vorm als de reden ertoe doet:
expected: accept
expected:
outcome: reject
reason: size_limit
De uitkomsten zijn accept, reject, sanitize en
unspecified. De redenen zijn een gesloten lijst zodat een rapport erop kan
groeperen: content_malformed, count_limit,
dimensions_limit, duplicate, encoding_invalid,
extension_rule, filename_invalid, filename_too_long,
filename_traversal, malware_signature, mime_mismatch,
nesting_depth, none, size_limit en
size_zero.
Een reden noemt de regel die in het spel is, niet het oordeel. Daarom kan dezelfde
reden onder beide uitkomsten staan - een bestand één byte onder een limiet is
accept, en de regel waar het om gaat is nog steeds size_limit.
Wat staat er in het manifest?
Het wordt aan het einde van elke run naast de bestanden geschreven, ook bij een onderbroken run. Eén item per bestand:
{
"manifest_version": "1.0",
"tool": { "name": "testing-files-generator", "version": "0.4.0" },
"run": {
"id": "run_b359aa8d94",
"seed": 0,
"command": "tfg generate --format png --size 2mb --out ./out",
"platform": { "os": "windows", "arch": "amd64" },
"complete": true
},
"summary": {
"file_count": 1,
"total_bytes": 2097152,
"by_format": { "png": 1 },
"by_expected": { "unspecified": 1 }
},
"files": [
{
"path": "files_0001.png",
"bytes": 2097152,
"format": "png",
"fidelity": "full",
"determinism": "byte",
"seed": "8dc2d18c",
"hashes": { "sha256": "1a1f7c..." },
"properties": { "width": 640, "height": 480 },
"expected": {
"outcome": "unspecified",
"detail": "No expectation was declared for this file.",
"confidence": "policy_dependent"
}
}
]
}
Er komt een recipe_hash bij als de run uit een recept kwam, en preset met
overrides als hij uit een preset kwam, zodat een manifest altijd te herleiden is
tot wat het maakte.
Elk item draagt ook target_id, de id van het target in het recept dat het bestand
maakte, en summary.by_target telt de bestanden waar elk target op uitkwam. Een
recept met meerdere targets kan zo target voor target worden gecontroleerd zonder bestandsnamen
te lezen.
Wat is een preset?
Een kant-en-klare set bestanden die een veelvoorkomende testvraag beantwoordt, zodat je de set niet
zelf hoeft te ontwerpen. Presets zijn gewone recepten onder de motorkap, en eject
drukt het recept af zodat je het vanaf daar kunt bewerken. Elke preset heeft
een eigen pagina met wat hij meestal vindt, wat er in de set zit en
welke instellingen hij kent.
-
Komt een geldig bestand dat zo klein is als het formaat toestaat door de controle?
empty-and-minimal -
Slaat mijn systeem een bestandsnaam op, toont en geeft het die terug, ook als het die niet verwachtte?
filename-handling -
Wordt een groottelimiet precies afgedwongen waar hij is opgegeven?
size-boundaries -
Overleeft mijn tabelimport wat echte tools exporteren?
tabular-import -
Weet mijn lezer in welke codering een bestand staat, of gokt hij?
text-encoding -
Neemt mijn uploadformulier aan wat het moet en weigert het de rest?
upload-validation
tfg preset list
tfg preset show size-boundaries
tfg generate --preset size-boundaries --limit 10mb --out ./edges
tfg preset eject size-boundaries > my.yaml
show zegt je wat de set zou kosten voordat je hem bouwt, en zegt zonder omwegen wanneer
een getal een tijdelijke waarde van ons is in plaats van een limiet van jou.
Wat betekenen de afsluitcodes?
Elk einde heeft zijn eigen code, machineleesbare uitvoer gaat naar de standaarduitvoer, en een mislukte run drukt daar niets af. De tabel is een bevroren contract - de betekenis van een code wijzigen vereist een major-versie.
| Code | Betekenis |
|---|---|
0 |
Alles werkte. |
1 |
Een onverwachte fout in de tool. |
2 |
Verkeerde opdracht of optie. |
3 |
Het recept is niet geldig. |
4 |
Het formaat kan niet wat er gevraagd werd. |
5 |
Een lees- of schrijfactie is mislukt. |
6 |
Niet genoeg schijfruimte. |
7 |
verify vond een afwijking. |
8 |
De run is klaar, maar niet alles is gemaakt. |
130 |
Onderbroken met Ctrl+C. |
143 |
Gestopt door een signaal, zo ziet een CI-timeout eruit. |
- name: build the fixtures
run: tfg generate fixtures.yaml --out ./fixtures
- name: run the tests
run: pytest tests/
- name: nothing moved
run: tfg verify ./fixtures/manifest.json
Een run die met Ctrl+C is gestopt laat nog steeds een manifest achter en nooit een half geschreven bestand, zodat een afgebroken taak door de volgende nog kan worden opgeruimd.
Kant-en-klare workflows voor GitHub Actions en GitLab CI: hoe genereer je testbestanden in een CI-pipeline.
Is er een bureaubladvenster?
Ja, dezelfde engine met een venster erop, voor het testen dat niet geautomatiseerd is. Het is geen uitgeklede versie: een test vergelijkt de twee interfaces mogelijkheid voor mogelijkheid, en alles wat maar één van beide kan moet worden verklaard en gerechtvaardigd in plaats van ongemerkt uit elkaar te drijven.
De schermen zijn één batch, presets, meerdere batches tegelijk en info. Het toont wat een run zou kosten voordat er iets wordt geschreven, meldt de voortgang terwijl het draait en kan halverwege worden afgebroken zonder een half geschreven bestand achter te laten. Het opent nog geen receptbestand - recepten zijn voorlopig iets van de opdrachtregel, en het venster bouwt zijn batches in het formulier.