This directory contains useful test code for testing various bits
of Apache functionality.  This stuff is for the developers only,
so we might remove it on public releases.


Python / pytest test suites
===========================

There are two complementary Python (pytest) test suites in this directory.
Both run against an already-built httpd; they are independent of each other.

  pyhttpd / modules/   httpd's own test framework.  Covers HTTP/2, mod_md
                       (ACME), HTTP/1, proxy and core behaviour.  Drives the
                       server with external clients (curl, nghttp, h2load) and
                       is configured via pyhttpd/config.ini (generated by
                       httpd's configure).  Framework code lives in pyhttpd/;
                       tests live in modules/{core,http1,http2,md,proxy}/.

  pytest_suite/        A self-contained port of the classic Perl Apache::Test
                       suite (core HTTP, per-module tests, security/CVE
                       regressions, SSL/TLS, PHP).  Drives the server with an
                       in-process Python HTTP client (httpx) and raw sockets.
                       It is fully self-contained: it ships its own conf
                       templates, document root, C test modules and helper
                       framework under pytest_suite/, and reads nothing outside
                       that directory.  See pytest_suite/README.md for details,
                       including how to add new tests.

The two suites coexist: pytest_suite/ has its own conftest.py and
pyproject.toml, so pytest treats it as its own rootdir and does NOT pick up
this directory's pyhttpd conftest.py.  Run pytest_suite from inside
pytest_suite/ (or via the unified runner below) -- do not point pytest at the
top-level test/ directory expecting to run both at once.


Unified runner: run-all-tests.sh
---------------------------------

run-all-tests.sh runs BOTH suites against the same built httpd and reports a
combined result.  pytest_suite runs first, then the pyhttpd modules/ tests.

  ./run-all-tests.sh                  # run both suites (pytest_suite first)
  ./run-all-tests.sh --only=pysuite   # only the pytest_suite tests
  ./run-all-tests.sh --only=pyhttpd   # only the pyhttpd modules/ tests
  ./run-all-tests.sh --apxs=/path/to/apxs   # point at a specific httpd build
  ./run-all-tests.sh -k status -v     # flags pass through to BOTH suites

How it finds the httpd build:
  * pytest_suite is located via apxs -- from --apxs, the $APXS environment
    variable, the "prefix" in pyhttpd/config.ini, or apxs on $PATH.
  * the pyhttpd tests use pyhttpd/config.ini (built by httpd's configure), via
    the system "pytest".

Selecting tests:
  * Flag arguments (-v, -k NAME, -x, ...) are passed to both suites.
  * Positional test paths are passed only to pytest_suite (they are
    pytest_suite paths).  Select pyhttpd tests with the PYHTTPD_TARGETS
    environment variable, e.g.
        PYHTTPD_TARGETS="modules/http2" ./run-all-tests.sh --only=pyhttpd
    By default the pyhttpd side runs every modules/* directory whose conftest
    imports successfully in your environment; a directory whose optional
    dependency is missing (e.g. modules/md needs pyOpenSSL) is skipped with a
    note rather than aborting the run.

Environment overrides:
  APXS             path to apxs (default: pyhttpd/config.ini prefix, else PATH)
  PHP_FPM          path to a php-fpm binary; enables pytest_suite's PHP tests
  PYHTTPD_TARGETS  pyhttpd test path(s) to run (default: auto-detected modules/*)

The runner exits non-zero if either suite has failures.


Running a suite directly
------------------------

Both runtests.sh scripts create their own virtualenv on first run and can be
invoked from any directory -- the paths below are just the convenient way to
type them. The venv is (re)built automatically whenever it is missing or its
pyproject.toml has changed, using `uv sync` (uv reads pyproject.toml + uv.lock).
uv (https://docs.astral.sh/uv/) is required. To force a clean rebuild yourself,
`rm -rf <suite>/.venv`.

pytest_suite (self-contained; the venv holds only pytest + httpx):

  ./pytest_suite/runtests.sh --apxs=/path/to/apxs            # all tests
  ./pytest_suite/runtests.sh --php-fpm=/path/to/php-fpm tests/t/php   # PHP tests
  ./pytest_suite/runtests.sh -k rewrite -v                   # any pytest args pass through

pyhttpd tests (need pyhttpd/config.ini from httpd's configure, plus curl,
nghttp2/h2load, and -- for modules/md -- pyOpenSSL and an ACME test server):

  ./pyhttpd/runtests.sh modules/http2       # all HTTP/2 tests
  ./pyhttpd/runtests.sh modules/core -k test_001   # a subset

Other contents
--------------

  unit/                C-based unit tests (libcheck / httpdunit).
  clients/             helper client programs used by the tests.
  *.c                  small standalone C test programs.
