Testing Files Generator
Polski

Jak zrobić uszkodzony plik do testów

Walidator, któremu pokazywano tylko zdrowe pliki, nie został naprawdę przetestowany. Oto jak dostać plik zepsuty celowo, o dokładnie takim rozmiarze, jaki podasz, z manifestem mówiącym, co system ma z nim zrobić.

Krótka odpowiedź

tfg generate --format png --size 2mb --damage zero-head --out ./out zapisuje PNG o dokładnie 2097152 bajtach, którego pierwsze bajty są zerami, a manifest obok zapisuje, że system powinien go odrzucić.

Zwykła droga

Dlaczego plik uszkodzony ręcznie to kiepski test

Zwykle używa się edytora szesnastkowego, skryptu zmieniającego kilka losowych bajtów albo ucięcia pliku przez head lub truncate. Za pierwszym razem działa, a potem kosztuje:

Co dostajesz

Uszkodzony plik ma nadal rozmiar, o który prosiłeś

Plik jest generowany normalnie, a psuty dopiero w drodze na dysk. Zachowuje rozmiar, który podałeś, a to samo polecenie zapisuje znowu te same bajty.

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

Ustawienia podaje się po dwukropku. Flagę można powtarzać, a uszkodzenia są stosowane w kolejności, w jakiej je zapiszesz. Działa z każdym z 26 formatów.

Co potrafi

Jakie są uszkodzenia?

To lista, którą wypisuje program, odczytana z niego w chwili budowania tej strony. tfg damage wypisuje to samo, a tfg damage <id> mówi, co przyjmuje jedno z nich.

Uszkodzenie Co robi z bajtami Najmniejszy plik Ustawienia
zero-head Nadpisuje pierwsze bajty pliku zerami, nie zmieniając jego długości. Większość czytników zagląda tam najpierw, więc to uszkodzenie zauważy prawie wszystko. 8 bytes

zero-head zapisuje zera na początku pliku. Większość czytników zagląda tam najpierw, w sygnaturę i nagłówek mówiące, czym jest plik, więc zauważy to prawie każdy czytnik. Zwykły tekst i logi nie mają sygnatury i też są odrzucane, bo ciąg zerowych bajtów nie jest tekstem. Poniżej czterech bajtów niektóre formaty wychodzą z uszkodzeniem, na które nie skarży się żaden czytnik, dlatego ustawienie zaczyna się od czterech.

Co mówi manifest

Manifest, który mówi, co ma się stać

Każdy uszkodzony plik dostaje wpis mówiący, że system powinien go odrzucić, a obok zapisane jest uszkodzenie:

"expected": {
  "outcome": "reject",
  "reason": "content_malformed",
  "confidence": "certain"
},
"damage": [
  {
    "type": "zero-head",
    "settings": {
      "bytes": "8"
    }
  }
]

Dwie prośby są odrzucane, zanim cokolwiek powstanie, bo każda zostawiłaby na dysku plik, który manifest opisuje błędnie:

W przepisie

Zdrowe i zepsute pliki w jednym przebiegu

Włóż jedno i drugie do jednego przepisu, a manifest niesie oczekiwanie każdego pliku, więc test nie potrzebuje listy, który jest który:

version: 1
targets:
  - id: healthy
    format: pdf
    size: 1mb
    expected: accept
  - id: broken
    format: pdf
    size: 1mb
    damage:
      - zero-head

W teście

Zamiana tego w test

Test czyta manifest i sprawdza, czy to, co się stało, jest tym, co zadeklarowano. Nie potrzebuje listy nazw plików:

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

Dobre odrzucenie jest czyste. Komunikat mówiący, co było nie tak, to odpowiedź, o którą chodzi. Błąd serwera, zawieszenie albo plik zapisany do połowy to wada, którą ten test ma znaleźć.

Dalej

Dokąd pójść stąd