Cum faci un fișier corupt pentru teste
Un validator căruia i s-au arătat doar fișiere sănătoase nu a fost cu adevărat testat. Iată cum obții un fișier stricat intenționat, care iese cu exact mărimea pe care o ceri și vine cu un manifest care spune ce trebuie să facă sistemul tău cu el.
Răspunsul scurt
tfg generate --format png --size 2mb --damage zero-head --out ./out scrie un PNG de
exact 2097152 de octeți ai cărui primi octeți sunt zerouri, iar manifestul de lângă el notează
că sistemul tău trebuie să îl respingă.
Calea obișnuită
De ce un fișier corupt de mână face un test prost
Căile obișnuite sunt un editor hexazecimal, un script care schimbă câțiva octeți la întâmplare sau
un fișier scurtat cu head ori truncate. Merg o dată, apoi te costă:
- Este altfel de fiecare dată. Un octet ales la întâmplare cade în alt loc la fiecare rulare, deci o eroare de marți poate să nu se mai întoarcă miercuri.
- Schimbă mărimea. Un fișier tăiat este mai mic decât limita sub care trebuia să stea, deci verificarea mărimii răspunde înaintea celei a conținutului, iar testul trece din motivul greșit.
- Adesea trece neobservat. Textul simplu se citește în continuare cu un octet schimbat la mijloc, iar un cititor de imagini îngăduitor îl desenează pur și simplu, așa că fișierul care trebuia să fie stricat este acceptat.
- Nu spune nimic despre ce trebuie să se întâmple. Fișierul este doar octeți, iar cine citește testul mai târziu trebuie să ghicească dacă s-a urmărit acceptarea sau respingerea.
Ce primești
Un fișier deteriorat are în continuare mărimea cerută
Fișierul este generat normal și stricat după aceea, pe drumul spre disc. Păstrează mărimea cerută, iar aceeași comandă scrie din nou aceiași octeți.
tfg generate --format png --size 2mb --damage zero-head --out ./out
tfg generate --format pdf --size 1mb --count 5 --damage zero-head:bytes=16 --out ./broken
Setările se scriu după două puncte. Opțiunea poate fi repetată, iar deteriorările se aplică în ordinea în care le scrii. Funcționează cu fiecare dintre cele 26 formate.
Ce poate face
Ce deteriorări există?
Aceasta este lista pe care o afișează programul, citită din el când se construiește pagina.
tfg damage o afișează pe aceeași, iar tfg damage <id> spune ce
primește una dintre ele.
| Deteriorare | Ce face cu octeții | Cel mai mic fișier | Setări |
|---|---|---|---|
zero-head |
Suprascrie cu zerouri primii octeți ai fișierului, fără să îi schimbe lungimea. Majoritatea cititorilor se uită întâi acolo, deci aproape orice observă această deteriorare. | 8 | bytes |
zero-head scrie zerouri peste începutul fișierului. Majoritatea cititorilor se uită
întâi acolo, la semnătura și antetul care spun ce este fișierul, așa că aproape orice cititor
observă. Textul simplu și jurnalele nu au semnătură și sunt respinse și ele, pentru că un șir de
octeți nuli nu este text. Sub patru octeți, unele formate ies cu o deteriorare de care nu se
plânge niciun cititor, de aceea setarea începe de la patru.
Ce spune manifestul
Un manifest care spune ce trebuie să se întâmple
Fiecare fișier deteriorat primește o intrare care spune că sistemul tău trebuie să îl respingă, cu deteriorarea notată alături:
"expected": {
"outcome": "reject",
"reason": "content_malformed",
"confidence": "certain"
},
"damage": [
{
"type": "zero-head",
"settings": {
"bytes": "8"
}
}
]
Două cereri sunt refuzate înainte să se scrie ceva, pentru că fiecare ar lăsa pe disc un fișier pe care manifestul îl descrie greșit:
- un fișier mai mic decât are nevoie deteriorarea, care ar ieși neschimbat
-
expected: acceptlângă o deteriorare, pentru că nimic nu ar putea îndeplini asta. Scriesanitizedacă sistemul tău trebuie să repare fișierul sauunspecifieddacă tocmai asta este întrebarea pe care o pui
Într-o rețetă
Fișiere sănătoase și stricate într-o singură rulare
Pune-le pe amândouă într-o rețetă, iar manifestul poartă așteptarea fiecărui fișier, deci testul nu are nevoie de o listă cu care este care:
version: 1
targets:
- id: healthy
format: pdf
size: 1mb
expected: accept
- id: broken
format: pdf
size: 1mb
damage:
- zero-head
Într-un test
Transformarea într-un test
Testul citește manifestul și verifică dacă ce s-a întâmplat este ce s-a declarat. Nu are nevoie de o listă de nume de fișiere:
import json, os
directory = "healthy-and-broken"
manifest = json.load(open(os.path.join(directory, "manifest.json")))
for entry in manifest["files"]:
response = upload(os.path.join(directory, entry["path"]))
if entry["expected"]["outcome"] == "reject":
assert not response.ok
else:
assert response.ok
O respingere bună este una curată. Un mesaj care spune ce a fost greșit este răspunsul pe care îl vrei. O eroare de server, o blocare sau un fișier salvat pe jumătate este defectul pe care acest test există ca să îl găsească.
Mai departe
Unde să mergi de aici
- Presetarea upload-validation pune unui formular celelalte două întrebări, cea despre mărime și cea despre tip.
- Fișiere de test în CI rulează într-un pipeline o rețetă ca aceasta.
-
Documentația cuprinde fiecare opțiune a lui
tfg generate.