diff --git a/.bruno/README.md b/.bruno/README.md index 6d4cb1d2..0bb251ab 100644 --- a/.bruno/README.md +++ b/.bruno/README.md @@ -1,6 +1,6 @@ # Bruno API Collection -A [Bruno](https://www.usebruno.com/) collection lives in `.bruno/` and mirrors every Gotenberg route. When adding or updating a route, update the collection to match. +A [Bruno](https://www.usebruno.com/) collection in `.bruno/` mirrors every Gotenberg route. Update the collection when adding or updating a route. ## Structure @@ -51,10 +51,10 @@ headers { ## Conventions -- **Mandatory fields** are listed without prefix; **optional fields** are prefixed with `~` (disabled by default in Bruno). +- **Mandatory fields** have no prefix; **optional fields** use the `~` prefix (disabled by default in Bruno). - **File references** use relative paths to `test/integration/testdata/`. -- **Webhook and output filename headers** are included on every POST route as optional (`~`). -- **One `.bru` file per request**. For routes with read/write variants (e.g., bookmarks, metadata), create separate files in the same folder. +- **Webhook and output filename headers** appear on every POST route as optional (`~`). +- **One `.bru` file per request.** For routes with read/write variants (e.g., bookmarks, metadata), create separate files in the same folder. ## Checklist When Adding/Updating a Route @@ -62,4 +62,4 @@ headers { 2. Include all form fields from the route handler. Check `FormData*` calls in the route function. 3. For file upload fields (`files`, `watermark`, `stamp`, `embeds`), use `@file(...)` with a suitable test file. 4. Verify the URL path matches the route's `Path` field exactly. -5. If you add a new module folder, keep the naming consistent (e.g., `PDF Engines/Rotate/`). +5. For new module folders, keep the naming consistent (e.g., `PDF Engines/Rotate/`). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5833efec..a736255f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -84,12 +84,12 @@ Stage only the files related to the change. Do not use `git add -A` or `git add ## Core Principles -- **Backward compatibility is law.** Never modify existing CLI flags, environment variables, or API form fields unless explicitly instructed to perform a breaking change. Flag any breaking change immediately. +- **Backward compatibility is law.** See the [Review Checklist](#review-checklist) for the full list of what must not change. - **Defensive programming.** Assume input is malformed. Handle errors explicitly. Never panic. - **Atomic commits.** One feature or fix per PR. Isolate refactoring from feature work. - **Idiomatic Go.** Follow "Effective Go" principles. All exported symbols must have GoDoc comments starting with their name. -## Project Layout +## Project Layout and Navigation ``` cmd/gotenberg/ → Entry point only (wiring/startup). No business logic. @@ -103,34 +103,21 @@ build/ → Dockerfile, fonts, Chromium config. Key interfaces live in `pkg/gotenberg/`: `Module`, `Provisioner`, `Validator`, `Debuggable`. Every module implements `Descriptor()` and self-registers. When adding features, determine if they belong in an existing module or require a new one. -## Codebase Navigation - -- Start with `pkg/gotenberg/` for core interfaces and `pkg/modules/` for feature implementations. - The integration test infrastructure in `test/integration/scenario/` is well-structured. Read `scenario.go` and `containers.go` to understand the Gherkin step definitions before writing new tests. - Mocks for all major interfaces are in `pkg/gotenberg/mocks.go`. Use them for unit tests rather than creating new ones. -- Import ordering is enforced: standard library, third-party, then `github.com/gotenberg/gotenberg/v8`, separated by blank lines. - When making changes, run only the relevant integration test tag rather than the full suite (40min timeout). - Telemetry infrastructure lives in `pkg/gotenberg/telemetry.go` (global Logger, Tracer, Meter) and `pkg/gotenberg/internal/` (log handlers, OTEL SDK init). HTTP semantic conventions are in `pkg/gotenberg/semconv/`. ---- - ## Makefile: the Only Build Interface -All build and verification tasks go through the Makefile. Do not run `go` commands directly unless debugging a specific package. +All build and verification tasks go through the Makefile. Do not run `go` commands directly unless debugging a specific package. The [Development Loop](#development-loop) covers the commands used during daily work. Additional commands: -| Command | Purpose | When to use | -| ----------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------- | -| `make build` | Build the Docker image | Before integration tests, or to verify compilation | -| `make run` | Run Gotenberg container via `docker compose` | Manual testing. Flags are configured via Makefile variables and compose.yaml | -| `make telemetry` | Start OpenTelemetry collector and OpenObserve | When testing telemetry locally | -| `make down` | Stop all compose containers | After manual testing | -| `make fmt` | Format Go code (`go fix`, `golangci-lint fmt`, `go mod tidy`) | Before every commit | -| `make lint` | Lint Go code (strict `.golangci.yml` config) | Before every commit. Zero errors permitted | -| `make lint-prettier` | Lint non-Go files (Markdown, YAML, etc.) with Prettier | Before every commit | -| `make prettify` | Format non-Go files (Markdown, YAML, etc.) with Prettier | Before every commit | -| `make test-unit` | Run unit tests (`go test -race ./...`) | After code changes to `pkg/` | -| `make test-integration` | Run integration tests (Gherkin/Godog, 40min timeout) | After any feature or route change | -| `make godoc` | Serve GoDoc at `localhost:6060` | To verify documentation | +| Command | Purpose | When to use | +| ---------------- | --------------------------------------------- | ---------------------------------------------------------------------------- | +| `make run` | Run Gotenberg container via `docker compose` | Manual testing. Flags are configured via Makefile variables and compose.yaml | +| `make telemetry` | Start OpenTelemetry collector and OpenObserve | When testing telemetry locally | +| `make down` | Stop all compose containers | After manual testing | +| `make godoc` | Serve GoDoc at `localhost:6060` | To verify documentation | ## Module System @@ -152,6 +139,49 @@ When adding a feature, first determine if it belongs in an existing module. Only - **Telemetry:** External tool calls (Chromium, LibreOffice, PDF engines, webhooks, downloads) must create OTEL spans with `trace.SpanKindClient` and `semconv.ServerAddress("toolname")`. Use `gotenberg.Tracer()` and `gotenberg.Meter()` for traces and metrics respectively. - **No business logic in `cmd/`:** The `cmd/gotenberg/` package is strictly for wiring and startup. +## Documentation + +### Writing Style + +- **Short, declarative sentences.** Say what it does, then stop. +- **Lead with the action.** "Validates font embedding" not "This function validates font embedding". +- **Active voice.** "Gotenberg checks the profile" not "The profile is checked by Gotenberg". +- **No em dashes.** Use a period, colon, or comma instead. +- **No "we" hedging.** "Don't..." not "We do not recommend...". + +### Godoc + +All exported types and functions require Godoc comments. Start with the identifier name: + +```go +// Violation records a single rule violation with context. +type Violation struct { ... } + +// ValidatePDFA audits the document against a PDF/A profile. +func ValidatePDFA(ctx context.Context, ...) ([]error, error) +``` + +Each package should have a `doc.go` with a `// Package foo ...` comment. + +Reference other identifiers with square brackets so pkg.go.dev renders them as links: + +```go +// ValidatePDFA returns violations as []error where each element is a +// [Violation] value. See [Rule] for the structured rule fields. +// The document must be opened via [pdf.Open] with an [io.ReaderAt]. +``` + +This works for same-package identifiers (`[Violation]`), other packages (`[io.Reader]`), and methods (`[Reader.Open]`). + +### Code Comments + +- Explain _why_, not _what_. The code shows what; the comment explains the non-obvious reasoning. +- No numbered step comments (`// 1. Do X`, `// 2. Do Y`). +- No section dividers with numbers (`// --- 8. Foo ---`). Plain dividers are fine for major boundaries (`// --- VeraPDF ---`). +- No noise comments that restate the code (`// Check if err is nil`, `// Return results`). +- Reference spec clauses where relevant (`// Per ISO 32000-2, Table 116...`). +- Mark technical debt with `// TODO: [context]`. + --- ## Review Checklist @@ -171,13 +201,7 @@ If any of these are violated, the change **must** be flagged as a breaking chang The `.golangci.yml` enforces strict rules including: `gosec`, `govet`, `errcheck`, `staticcheck`, `dupl`, `bodyclose`, `exhaustive`, `errname`, `sloglint`, `gocritic`, and more. Zero linting errors are permitted. -Formatters enforce `gci`, `gofmt`, `gofumpt`, `goimports` with import ordering: - -1. Standard library -2. Third-party packages -3. `github.com/gotenberg/gotenberg/v8` - -Three groups separated by blank lines. +Formatters enforce `gci`, `gofmt`, `gofumpt`, `goimports` (see import ordering in [Coding Patterns](#coding-patterns)). ### Code Quality @@ -189,16 +213,19 @@ Three groups separated by blank lines. ### Documentation -- Every exported function, type, constant, and variable has a GoDoc comment starting with its name. +- Every exported function, type, constant, and variable has a Godoc comment starting with its name (see [Godoc](#godoc)). - New packages include a `doc.go` file. - `README.md` is not modified unless explicitly requested. +- All documentation follows the [Writing Style](#writing-style) and [Code Comments](#code-comments) guidelines. --- ## Scoped Guidelines -Detailed guidelines for specific areas of the codebase: +Some areas of the codebase have their own README with detailed instructions: -- [`test/integration/README.md`](test/integration/README.md): Integration test framework, Gherkin step reference, available tags, and how to write new tests. -- [`.bruno/README.md`](.bruno/README.md): Bruno API collection structure, `.bru` file format, conventions, and route update checklist. -- [`pkg/modules/pdfengines/README.md`](pkg/modules/pdfengines/README.md): How to add new PDF engine features (Makefile variable and flag). +| Area | README | Covers | +| ----------------- | ---------------------------------------------------------------------- | --------------------------------------------------------- | +| Integration tests | [`test/integration/README.md`](test/integration/README.md) | Gherkin step reference, available tags, writing new tests | +| Bruno collection | [`.bruno/README.md`](.bruno/README.md) | `.bru` file format, conventions, route update checklist | +| PDF engines | [`pkg/modules/pdfengines/README.md`](pkg/modules/pdfengines/README.md) | Adding new engine features (Makefile variable and flag) | diff --git a/SECURITY.md b/SECURITY.md index dfdf3cdd..61356d91 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,7 @@ ## Supported Versions -Only the latest version of Gotenberg receives security updates and patches. Keep your environment up to date. +Only the latest version receives security updates and patches. Keep your environment up to date. ## Reporting a Vulnerability @@ -12,18 +12,18 @@ Include: - A detailed description of the vulnerability. - Steps to reproduce the issue. -- Any potential impact on users or the system. +- Potential impact on users or the system. -This process is handled on a _'best-effort'_ basis. Response speed may vary depending on severity and available resources. +This process is handled on a best-effort basis. Response speed may vary depending on severity and available resources. ## Disclosure Policy -Once a vulnerability report is received and confirmed: +Once a report is received and confirmed: - A fix and release timeline will be prepared. -- You will be notified when the fix is released. -- You will be credited for the discovery (unless you request anonymity). +- The reporter will be notified when the fix is released. +- The reporter will be credited for the discovery (unless anonymity is requested). ## Comments on this Policy -If you have suggestions on how this process could be improved, submit a pull request. +Submit a pull request with suggestions for improving this process. diff --git a/pkg/gotenberg/doc.go b/pkg/gotenberg/doc.go index 100ea8f6..c8cea07a 100644 --- a/pkg/gotenberg/doc.go +++ b/pkg/gotenberg/doc.go @@ -1,7 +1,7 @@ -// Package gotenberg provides most of the logic of the module system. +// Package gotenberg implements the core module system. // -// caddyserver/caddy, licensed under the Apache License 2.0, has significantly -// inspired this module system. +// Significantly inspired by caddyserver/caddy, licensed under the Apache +// License 2.0. // -// More details are available on https://caddyserver.com/. +// See https://caddyserver.com/. package gotenberg diff --git a/pkg/gotenberg/internal/otel/doc.go b/pkg/gotenberg/internal/otel/doc.go index dd12008f..a97372dd 100644 --- a/pkg/gotenberg/internal/otel/doc.go +++ b/pkg/gotenberg/internal/otel/doc.go @@ -1,8 +1,7 @@ // Package otel gathers initialization utilities for OpenTelemetry // instrumentation. // -// This package has been significantly inspired by -// https://github.com/lucavallin/gotel. +// Significantly inspired by https://github.com/lucavallin/gotel. // -// See: https://opentelemetry.io/. +// See https://opentelemetry.io/. package otel diff --git a/pkg/gotenberg/semconv/doc.go b/pkg/gotenberg/semconv/doc.go index 2a6751b7..970912ef 100644 --- a/pkg/gotenberg/semconv/doc.go +++ b/pkg/gotenberg/semconv/doc.go @@ -1,7 +1,5 @@ -// Package semconv is a copy/paste of utilities that are currently not exposed -// in the OpenTelemery Go SDK. +// Package semconv contains utilities not yet exposed in the OpenTelemetry Go +// SDK. Remove this package once an official API exists. // -// This package MUST be removed once an "official" API is provided. -// -// See: https://github.com/open-telemetry/opentelemetry-go-contrib/issues/4580. +// See https://github.com/open-telemetry/opentelemetry-go-contrib/issues/4580. package semconv diff --git a/pkg/modules/api/doc.go b/pkg/modules/api/doc.go index 8b9c119e..1821ec3c 100644 --- a/pkg/modules/api/doc.go +++ b/pkg/modules/api/doc.go @@ -1,3 +1,3 @@ -// Package api provides a module, which is an HTTP server. Other modules may -// add multipart/form-data routes, middlewares, and health checks. +// Package api implements the HTTP server module. Other modules register +// multipart/form data routes, middlewares, and health checks through it. package api diff --git a/pkg/modules/chromium/doc.go b/pkg/modules/chromium/doc.go index 7b64233a..188f0252 100644 --- a/pkg/modules/chromium/doc.go +++ b/pkg/modules/chromium/doc.go @@ -1,4 +1,3 @@ -// Package chromium provides a module which adds routes for converting HTML -// documents to PDF. Other modules may also retrieve the [Api] provided by this -// module. +// Package chromium adds routes for converting HTML documents to PDF. Exposes +// an [Api] for other modules. package chromium diff --git a/pkg/modules/exiftool/doc.go b/pkg/modules/exiftool/doc.go index e9ae0a7f..21cb541c 100644 --- a/pkg/modules/exiftool/doc.go +++ b/pkg/modules/exiftool/doc.go @@ -1,11 +1,6 @@ -// Package exiftool provides an implementation of the gotenberg.PdfEngine -// interface using the ExifTool command-line tool. This package allows for: +// Package exiftool implements gotenberg.PdfEngine using the ExifTool command-line tool. Reads and writes PDF metadata. // -// 1. The reading of metadata. -// 2. The writing of metadata. +// Requires the EXIFTOOL_BIN_PATH environment variable. // -// The path to the exiftool binary must be specified using the -// EXIFTOOL_BIN_PATH environment variable. -// -// See: https://exiftool.org. +// See https://exiftool.org. package exiftool diff --git a/pkg/modules/libreoffice/api/doc.go b/pkg/modules/libreoffice/api/doc.go index a09b3f5d..5edf7375 100644 --- a/pkg/modules/libreoffice/api/doc.go +++ b/pkg/modules/libreoffice/api/doc.go @@ -1,3 +1,2 @@ -// Package api provides a module which manages a LibreOffice instance and -// interacts with it via the UNO (Universal Network Objects) API. +// Package api manages a LibreOffice instance via the UNO API. package api diff --git a/pkg/modules/libreoffice/doc.go b/pkg/modules/libreoffice/doc.go index b628b195..6431587a 100644 --- a/pkg/modules/libreoffice/doc.go +++ b/pkg/modules/libreoffice/doc.go @@ -1,3 +1,3 @@ -// Package libreoffice provides a module which adds a route for converting -// documents to PDF with LibreOffice. +// Package libreoffice adds a route for converting documents to PDF with +// LibreOffice. package libreoffice diff --git a/pkg/modules/libreoffice/pdfengine/doc.go b/pkg/modules/libreoffice/pdfengine/doc.go index de89cef7..90ff6edb 100644 --- a/pkg/modules/libreoffice/pdfengine/doc.go +++ b/pkg/modules/libreoffice/pdfengine/doc.go @@ -1,6 +1,3 @@ -// Package pdfengine provides a module which interacts with LibreOffice via the -// UNO (Universal Network Objects) API and implements the gotenberg.PdfEngine -// interface. This package allows for: -// -// 1. The conversion to specific PDF formats. +// Package pdfengine implements gotenberg.PdfEngine using LibreOffice via the +// UNO API. Converts PDFs to specific PDF formats. package pdfengine diff --git a/pkg/modules/pdfcpu/doc.go b/pkg/modules/pdfcpu/doc.go index 6856a27a..9d46e567 100644 --- a/pkg/modules/pdfcpu/doc.go +++ b/pkg/modules/pdfcpu/doc.go @@ -1,8 +1,5 @@ -// Package pdfcpu provides an implementation of the gotenberg.PdfEngine -// interface using the pdfcpu command-line tool. This package allows for: +// Package pdfcpu implements gotenberg.PdfEngine using the pdfcpu command-line +// tool. Merges and splits PDF files. // -// 1. The merging of PDF files. -// 2. The splitting of PDF files. -// -// See: https://github.com/pdfcpu/pdfcpu. +// See https://github.com/pdfcpu/pdfcpu. package pdfcpu diff --git a/pkg/modules/pdfengines/README.md b/pkg/modules/pdfengines/README.md index baca3fdc..fdf973f5 100644 --- a/pkg/modules/pdfengines/README.md +++ b/pkg/modules/pdfengines/README.md @@ -1,14 +1,32 @@ # Adding PDF Engine Features -When adding a new PDF engine capability (e.g., bookmarks, watermark, stamp, embed), you must update the Makefile to include the corresponding engine list variable and flag. Every `--pdfengines-*-engines` flag registered in `pkg/modules/pdfengines/pdfengines.go` must have a matching entry in the Makefile: +Each new PDF engine capability (e.g., bookmarks, watermark, stamp, embed) requires a matching Makefile entry. The Makefile variables control which engines are passed to Gotenberg at `make run` and `make test-integration` time (via `compose.yaml`). If you skip this step, the flag still works when set manually, but `make run` falls back to the default defined in `pdfengines.go`, which may not include the new engine. -1. **Add a variable** in the Makefile's variable block (around line 60-70): +Every `--pdfengines-*-engines` flag registered in `pkg/modules/pdfengines/pdfengines.go` must have a corresponding variable and flag in the Makefile: + +1. **Add a variable** in the Makefile's variable block (around line 60 to 70): ```makefile PDFENGINES__ENGINES= ``` -2. **Add the flag** in the Makefile's command args block (around line 140-155): - ```makefile - --pdfengines--engines=$(PDFENGINES__ENGINES) \ +2. **Add the flag** in `compose.yaml`'s command args: + ```yaml + - "--pdfengines--engines=${PDFENGINES__ENGINES}" ``` -The default value should match what is defined in `pdfengines.go`'s `fs.StringSlice(...)` call for that flag. +The default value must match the `fs.StringSlice(...)` call for that flag in `pdfengines.go`. + +## Example: Rotate + +The rotate feature was added with two engines (`pdfcpu` and `pdftk`). Here is what the additions look like: + +**Makefile** (variable block): + +```makefile +PDFENGINES_ROTATE_ENGINES=pdfcpu,pdftk +``` + +**compose.yaml** (command args): + +```yaml +- "--pdfengines-rotate-engines=${PDFENGINES_ROTATE_ENGINES}" +``` diff --git a/pkg/modules/pdfengines/doc.go b/pkg/modules/pdfengines/doc.go index a6d46cc5..34f5e1ac 100644 --- a/pkg/modules/pdfengines/doc.go +++ b/pkg/modules/pdfengines/doc.go @@ -1,3 +1,3 @@ -// Package pdfengines a way to gather and manage multiple modules that -// implement the gotenberg.PdfEngine interface. +// Package pdfengines gathers and manages modules that implement +// gotenberg.PdfEngine. package pdfengines diff --git a/pkg/modules/pdftk/doc.go b/pkg/modules/pdftk/doc.go index c65403f7..2f7dcecc 100644 --- a/pkg/modules/pdftk/doc.go +++ b/pkg/modules/pdftk/doc.go @@ -1,11 +1,7 @@ -// Package pdftk provides an implementation of the gotenberg.PdfEngine -// interface using the PDFtk command-line tool. This package allows for: +// Package pdftk implements gotenberg.PdfEngine using the PDFtk command-line +// tool. Merges and splits PDF files. // -// 1. The merging of PDF files. -// 2. The splitting of PDF files. +// Requires the PDFTK_BIN_PATH environment variable. // -// The path to the PDFtk binary must be specified using the PDFTK_BIN_PATH -// environment variable. -// -// See: https://gitlab.com/pdftk-java/pdftk. +// See https://gitlab.com/pdftk-java/pdftk. package pdftk diff --git a/pkg/modules/prometheus/doc.go b/pkg/modules/prometheus/doc.go index f5b629c8..2a27211b 100644 --- a/pkg/modules/prometheus/doc.go +++ b/pkg/modules/prometheus/doc.go @@ -1,5 +1,4 @@ -// Package prometheus provides a module which collects metrics and exposes them -// via an HTTP route. +// Package prometheus collects metrics and exposes them via an HTTP route. // -// See: https://prometheus.io/. +// See https://prometheus.io/. package prometheus diff --git a/pkg/modules/qpdf/doc.go b/pkg/modules/qpdf/doc.go index 5f494a1f..d4fb564b 100644 --- a/pkg/modules/qpdf/doc.go +++ b/pkg/modules/qpdf/doc.go @@ -1,12 +1,7 @@ -// Package qpdf provides an implementation of the gotenberg.PdfEngine -// interface using the QPDF command-line tool. This package allows for: +// Package qpdf implements gotenberg.PdfEngine using the QPDF command-line +// tool. Merges, splits, and flattens PDF files. // -// 1. The merging of PDF files. -// 2. The splitting of PDF files. -// 3. Flattening of PDF files +// Requires the QPDF_BIN_PATH environment variable. // -// The path to the QPDF binary must be specified using the QPDK_BIN_PATH -// environment variable. -// -// See: https://github.com/qpdf/qpdf. +// See https://github.com/qpdf/qpdf. package qpdf diff --git a/pkg/modules/webhook/doc.go b/pkg/modules/webhook/doc.go index af5243c2..b2bb9d36 100644 --- a/pkg/modules/webhook/doc.go +++ b/pkg/modules/webhook/doc.go @@ -1,3 +1,3 @@ -// Package webhook provides a module which adds a middleware for uploading -// output files to any destination in an asynchronous fashion. +// Package webhook adds middleware for uploading output files to any destination +// asynchronously. package webhook diff --git a/pkg/standard/chromium/doc.go b/pkg/standard/chromium/doc.go index 939f0473..06d986d8 100644 --- a/pkg/standard/chromium/doc.go +++ b/pkg/standard/chromium/doc.go @@ -1,3 +1,3 @@ -// Package chromium imports the application's modules for the Chromium-only -// variant (no LibreOffice). +// Package chromium imports modules for the Chromium-only variant (no +// LibreOffice). package chromium diff --git a/pkg/standard/doc.go b/pkg/standard/doc.go index 46d336a0..f307ee23 100644 --- a/pkg/standard/doc.go +++ b/pkg/standard/doc.go @@ -1,2 +1,2 @@ -// Package standard imports the application's default modules. +// Package standard imports the default modules. package standard diff --git a/pkg/standard/libreoffice/doc.go b/pkg/standard/libreoffice/doc.go index a4fe86ea..3c9716e1 100644 --- a/pkg/standard/libreoffice/doc.go +++ b/pkg/standard/libreoffice/doc.go @@ -1,3 +1,3 @@ -// Package libreoffice imports the application's modules for the -// LibreOffice-only variant (no Chromium). +// Package libreoffice imports modules for the LibreOffice-only variant (no +// Chromium). package libreoffice diff --git a/test/integration/README.md b/test/integration/README.md index 53c6d803..0e58370c 100644 --- a/test/integration/README.md +++ b/test/integration/README.md @@ -2,15 +2,15 @@ - **Framework:** Gherkin (BDD) via [Godog](https://github.com/cucumber/godog), with `testcontainers-go` for Docker orchestration. - **Feature files:** `test/integration/features/*.feature`, one file per endpoint or capability. -- **Test infrastructure:** `test/integration/scenario/`, Go step definitions, container management, HTTP helpers, PDF validation. +- **Test infrastructure:** `test/integration/scenario/` contains Go step definitions, container management, HTTP helpers, and PDF validation. - **Entry point:** `test/integration/main_test.go` (build tag: `integration`). - **Test data:** `test/integration/testdata/` ## How It Works -Each scenario spins up a fresh Gotenberg Docker container via testcontainers. The step definitions in `scenario/scenario.go` map Gherkin steps to Go functions. An additional `gotenberg/integration-tools` container provides PDF validation tools (`verapdf`, `pdfinfo`, `pdftotext`). +Each scenario spins up a fresh Gotenberg Docker container via testcontainers. Step definitions in `scenario/scenario.go` map Gherkin steps to Go functions. A separate `gotenberg/integration-tools` container provides PDF validation tools (`verapdf`, `pdfinfo`, `pdftotext`). -**Important:** Integration tests require a Docker image. Run `make build` before `make test-integration`. +**Important:** Run `make build` before `make test-integration`. Integration tests require a Docker image. ## Selective Test Runs @@ -22,7 +22,14 @@ make test-integration TAGS=chromium-convert-html make test-integration TAGS="merge,split" ``` -Available tags: `chromium`, `chromium-concurrent`, `chromium-convert-html`, `chromium-convert-markdown`, `chromium-convert-url`, `chromium-screenshot-html`, `chromium-screenshot-markdown`, `chromium-screenshot-url`, `debug`, `health`, `libreoffice`, `libreoffice-convert`, `output-filename`, `pdfengines`, `pdfengines-convert`, `pdfengines-embed`, `embed`, `pdfengines-encrypt`, `encrypt`, `pdfengines-flatten`, `flatten`, `pdfengines-merge`, `merge`, `pdfengines-metadata`, `metadata`, `pdfengines-split`, `split`, `pdfengines-watermark`, `watermark`, `pdfengines-stamp`, `stamp`, `pdfengines-bookmarks`, `bookmarks`, `pdfengines-rotate`, `rotate`, `prometheus-metrics`, `root`, `version`, `webhook`, `download-from`. +Available tags: + +| Group | Tags | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Chromium | `chromium`, `chromium-concurrent`, `chromium-convert-html`, `chromium-convert-markdown`, `chromium-convert-url`, `chromium-screenshot-html`, `chromium-screenshot-markdown`, `chromium-screenshot-url` | +| LibreOffice | `libreoffice`, `libreoffice-convert` | +| PDF Engines | `pdfengines`, `pdfengines-convert`, `pdfengines-merge`, `merge`, `pdfengines-split`, `split`, `pdfengines-flatten`, `flatten`, `pdfengines-rotate`, `rotate`, `pdfengines-embed`, `embed`, `pdfengines-encrypt`, `encrypt`, `pdfengines-watermark`, `watermark`, `pdfengines-stamp`, `stamp`, `pdfengines-metadata`, `metadata`, `pdfengines-bookmarks`, `bookmarks` | +| Infrastructure | `health`, `debug`, `root`, `version`, `output-filename`, `prometheus-metrics`, `webhook`, `download-from` | Other useful flags: @@ -35,8 +42,8 @@ make test-integration PLATFORM=linux/arm64 # Force a specific platform 1. Create or update a `.feature` file in `test/integration/features/`. 2. Tag it appropriately (e.g., `@chromium @chromium-convert-html`). -3. If the feature requires new tag(s), add them to both the `TAGS` comment block in the `Makefile` and the "Available tags" list above. -4. If you create a new step definition, add it to `scenario/scenario.go`, register it in `InitializeScenario`, and update the "Available Gherkin Steps" list below. +3. For new tags, add them to both the `TAGS` comment block in the `Makefile` and the "Available tags" list above. +4. For new step definitions, add the function to `scenario/scenario.go`, register it in `InitializeScenario`, and add the step pattern to the "Available Gherkin Steps" list below (follow the existing format: backtick-quoted pattern, then parenthetical notes on arguments). 5. Test data goes in `test/integration/testdata/`. ## Available Gherkin Steps diff --git a/test/integration/doc.go b/test/integration/doc.go index d52de84a..0457fe07 100644 --- a/test/integration/doc.go +++ b/test/integration/doc.go @@ -1,2 +1,2 @@ -// Package integration contains everything related to integration testing. +// Package integration contains the integration test suite. package integration diff --git a/test/integration/testdata/pem/README.md b/test/integration/testdata/pem/README.md index e59b632c..d3628158 100644 --- a/test/integration/testdata/pem/README.md +++ b/test/integration/testdata/pem/README.md @@ -1,13 +1,13 @@ -To generate a valid certificate and private key use the following command: +Generate a valid certificate and private key: ```bash -# In OpenSSL ≥ 1.1.1 +# OpenSSL 1.1.1+ openssl req -x509 -newkey rsa:4096 -sha256 -days 9999 -nodes \ -keyout key.pem -out cert.pem -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1" ``` -To check a certificate use the following command: +Check a certificate: ```bash openssl x509 -in cert.pem -text