Testing Files Generator
한국어

문서

도구가 하는 모든 일을 사람들이 실제로 가져오는 질문 형태로 정리했습니다. 저장소의 README가 전체 레퍼런스이며, 내려받은 빌드와 항상 일치합니다.

어떤 명령이 있나요?

각 명령은 한 가지 일만 합니다.

tfg generate    레시피나 플래그로 파일을 만든다
tfg validate    레시피를 검사하고 아무것도 쓰지 않는다
tfg verify      디렉터리를 매니페스트와 대조해 검사한다
tfg cleanup     매니페스트에 나열된 파일을 삭제한다
tfg recipe fmt  레시피를 정돈된 형태로 출력한다
tfg preset      이름 붙은 테스트 질문으로 파일 세트를 만든다
tfg formats     이 빌드가 지원하는 형식을 나열한다
tfg damage      이 빌드가 파일을 일부러 망가뜨릴 수 있는 방법을 나열한다
tfg tool        이미 가진 파일을 위한 작은 도구
tfg version     도구 버전을 출력한다
tfg license     라이선스와 생성된 파일에 대한 의미를 출력한다

정확한 크기의 파일 하나는 어떻게 만드나요?

형식, 크기, 저장 위치를 지정합니다. 크기는 1024 단위로 세므로 2mb는 2097152바이트입니다. 바이트 수를 그대로 써도 되므로 --size 10485761은 정확히 그만큼을 요청합니다.

tfg generate --format png --size 2mb --out ./out

generate에서 유용한 플래그:

플래그동작
--format <id>파일의 형식. 예: txt
--size <size>각 파일의 정확한 크기. 10mb와 같은 값 또는 바이트 수
--size-range <a-b>범위에서 파일마다 뽑는 크기. 예: 1kb-8kb. 추첨은 시드에서 나옵니다
--boundary <size>한도 주변의 파일 세 개: 1바이트 아래, 한도 값, 1바이트 위
--count <n>만들 파일 수. 기본값은 1
--name <template>이름 템플릿. 예: invoice_{index:04}.txt
--out <dir>쓸 디렉터리
--seed <n>실행의 시드. 같은 시드는 같은 바이트를 만듭니다
--set <k>=<v>형식 설정, 여러 번 지정할 수 있음
--damage <name>파일을 일부러 망가뜨립니다. 여러 번 지정할 수 있으며 순서대로 적용됩니다. 목록은 tfg damage로 봅니다
--expected <outcome>accept, reject, sanitize, unspecified
--dry-run세어서 보여 주기만 하고 아무것도 쓰지 않음
--json매니페스트를 표준 출력에 씀

일부러 망가진 파일은 어떻게 만드나요?

이 도구가 쓰는 다른 모든 파일은 구조상 올바르며, 이는 업로드 검증기가 던지는 세 가지 질문 중 두 가지에 답합니다. --damage는 세 번째, 곧 파일이 아예 열리는지에 답합니다. 파일은 정상적으로 만들어진 뒤 망가지므로 요청한 크기는 그대로입니다.

tfg generate --format png --size 2mb --damage zero-head --out ./out
tfg generate --format png --size 2mb --damage zero-head:bytes=16 --out ./out

설정은 콜론 뒤에 씁니다. 플래그는 반복할 수 있으며, 쓴 순서가 적용 순서입니다. tfg damage는 이 빌드가 할 수 있는 것과 각각이 받는 값을 나열합니다.

레시피에서는 키가 이름 또는 설정의 목록입니다.

targets:
  - id: broken
    format: png
    count: 5
    size: 2mb
    damage:
      - zero-head
      - type: zero-head
        bytes: 16

손상된 파일은 매니페스트에서 expected: reject를 받고, 옆에 손상 내용이 기록됩니다. 두 가지는 아무것도 쓰기 전에 거부됩니다. 각각 매니페스트가 잘못 설명하는 파일을 디스크에 남기게 되기 때문입니다.

세 번째는 미리 알 수 없습니다. 손상이 실행되었는데 한 바이트도 바뀌지 않았다면 그 파일은 쓰이지 않고 버려집니다. 실행은 계속되고, 어떤 파일이었는지 알려 주며, 일부만 완료된 종료 코드로 끝납니다.

단계별로, 매니페스트를 읽는 테스트와 함께 설명합니다. 테스트용 손상 파일을 만드는 방법.

레시피는 어떻게 생겼나요?

레시피는 실행 전체를 기술하는 YAML 파일입니다. 테스트 옆에 커밋하면 픽스처는 더 이상 저장소의 바이너리가 아닙니다. 몇백 자짜리 파일만 있으면 누구나 바이트 단위로 똑같이 다시 만들 수 있습니다.

# 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

각 타깃에는 size, size-range, boundary, contains 중 정확히 하나가 필요합니다. 둘은 오류이고 하나도 없는 것도 오류입니다. 올바르지 않은 레시피는 파일을 하나도 쓰지 않으며, 첫 번째 문제만이 아니라 모든 문제를 한꺼번에 보고하고 각각 해당 설정의 이름을 알려 줍니다.

시스템이 파일을 어떻게 처리해야 하는지는 어떻게 선언하나요?

결과만 있으면 충분할 때는 짧은 형식을, 이유가 중요할 때는 긴 형식을 씁니다.

expected: accept
expected:
  outcome: reject
  reason: size_limit

결과는 accept, reject, sanitize, unspecified입니다. 이유는 닫힌 목록이라 보고서가 이유별로 묶을 수 있습니다. 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, size_zero.

이유가 가리키는 것은 판정이 아니라 문제가 되는 규칙입니다. 그래서 같은 이유가 어느 결과 아래에도 올 수 있습니다. 한도보다 1바이트 작은 파일은 accept이지만, 관련된 규칙은 여전히 size_limit입니다.

매니페스트에는 무엇이 들어 있나요?

중단된 실행을 포함해 모든 실행이 끝날 때 파일 옆에 쓰입니다. 파일마다 항목이 하나씩 있습니다.

{
  "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"
      }
    }
  ]
}

실행이 레시피에서 왔다면 recipe_hash가, 프리셋에서 왔다면 preset과 overrides가 추가되므로, 매니페스트는 항상 그것을 만든 출처까지 추적할 수 있습니다.

각 항목에는 파일을 만든 레시피 타깃의 id인 target_id도 들어 있고, summary.by_target은 각 타깃이 만든 파일 수를 셉니다. 따라서 타깃이 여러 개인 레시피도 파일 이름을 읽지 않고 타깃별로 확인할 수 있습니다.

프리셋이란 무엇인가요?

흔한 테스트 질문에 답하는 기성 파일 세트로, 세트를 직접 설계할 필요가 없습니다. 프리셋은 내부적으로 평범한 레시피이며, eject가 레시피를 출력하므로 거기서부터 편집할 수 있습니다. 각 프리셋에는 보통 무엇을 찾아내는지, 세트에 무엇이 들어 있는지, 어떤 설정을 받는지 설명하는 전용 페이지가 있습니다.

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는 세트를 만들기 전에 비용이 얼마나 드는지 알려 주고, 숫자가 여러분의 한도가 아니라 우리 쪽의 임시값일 때는 분명히 말해 줍니다.

종료 코드는 무엇을 뜻하나요?

끝나는 방식마다 고유한 코드가 있고, 기계가 읽을 수 있는 출력은 표준 출력으로 나가며, 실패한 실행은 거기에 아무것도 출력하지 않습니다. 이 표는 고정된 약속이며, 코드의 의미를 바꾸려면 메이저 버전을 올려야 합니다.

코드 의미
0 모두 정상적으로 동작했습니다.
1 도구 내부에서 예기치 않은 오류가 발생했습니다.
2 명령 또는 플래그가 잘못되었습니다.
3 레시피가 올바르지 않습니다.
4 해당 형식으로는 요청한 작업을 할 수 없습니다.
5 읽기 또는 쓰기에 실패했습니다.
6 디스크 공간이 부족합니다.
7 verify가 불일치를 발견했습니다.
8 실행은 끝났지만 모든 것이 만들어지지는 않았습니다.
130 Ctrl+C로 중단되었습니다.
143 시그널로 중지되었습니다. CI 시간 초과가 이렇게 보입니다.
- 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

Ctrl+C로 멈춘 실행도 매니페스트는 남기고, 쓰다 만 파일은 절대 남기지 않으므로, 취소된 작업을 다음 작업이 정리할 수 있습니다.

GitHub Actions와 GitLab CI용으로 바로 쓸 수 있는 워크플로. CI 파이프라인에서 테스트 파일을 생성하는 방법.

데스크톱 창이 있나요?

네. 같은 엔진 위에 창을 얹은 것으로, 스크립트로 하지 않는 테스트를 위한 것입니다. 축소판이 아닙니다. 테스트가 두 인터페이스를 기능별로 비교하며, 한쪽만 할 수 있는 것은 조용히 벌어지는 대신 선언하고 이유를 밝혀야 합니다.

화면은 단일 배치, 프리셋, 여러 배치 동시 실행, 정보입니다. 무엇이든 쓰기 전에 실행 비용을 보여 주고, 실행 중에는 진행 상황을 알려 주며, 쓰다 만 파일을 남기지 않고 도중에 취소할 수 있습니다. 아직 레시피 파일은 열지 못합니다. 지금은 레시피가 명령줄의 몫이고, 창은 양식에서 배치를 구성합니다.