mirror of
https://github.com/apache/httpd.git
synced 2026-10-23 22:49:01 +03:00
This port achieves 100% parity with the old PERL version. Create a single entry point for both the pyhttpd test suite already here and the new one. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1934933 13f79535-47bb-0310-9956-ffa450edef68
96 lines
3.9 KiB
Python
96 lines
3.9 KiB
Python
"""Test-facing helpers for translated httpd tests.
|
|
|
|
Phase 2 exposes a small, pytest-idiomatic surface that the translated ``.t``
|
|
files use. The Perl Apache::Test vocabulary maps as follows:
|
|
|
|
* ``plan tests => N`` -> dropped (pytest counts tests itself)
|
|
* ``ok $cond`` -> ``assert cond``
|
|
* ``ok t_cmp($got, $exp, $d)`` -> ``assert t_cmp(got, exp), d`` (see :func:`t_cmp`)
|
|
* ``need_module 'x'`` (in plan) -> ``@need_module("x")`` marker on the test
|
|
* ``have_min_apache_version()`` -> :func:`have_min_apache_version` (runtime gate)
|
|
* ``GET`` / ``GET_BODY`` / ... -> methods on the ``http`` fixture (client.py)
|
|
|
|
The requirement markers (need_*) are evaluated at collection time by a
|
|
``pytest_collection_modifyitems`` hook in conftest.py, which probes the target
|
|
httpd once and skips tests whose requirements aren't met -- the analog of
|
|
Apache::Test's plan-time skipping.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Assertions / comparison
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
def t_cmp(received: Any, expected: Any) -> bool:
|
|
"""Faithful port of Apache::TestUtil::t_cmp / t_is_equal.
|
|
|
|
* If ``expected`` is a compiled regex (``re.Pattern``), return whether it
|
|
matches ``received`` anywhere (Perl ``=~``, i.e. ``re.search``).
|
|
* Lists/tuples compare element-wise; dicts compare key/value-wise.
|
|
* ``None`` equals only ``None``.
|
|
* Otherwise compare by string equality, mirroring Perl's ``eq`` (both sides
|
|
stringified) so ``200 == "200"`` holds as in the Perl tests.
|
|
|
|
Returns a bool so callers write ``assert t_cmp(got, exp), "desc"`` -- the
|
|
description becomes the assertion message (the Perl 3rd arg / t_debug).
|
|
"""
|
|
if isinstance(expected, re.Pattern):
|
|
return expected.search(str(received)) is not None
|
|
if isinstance(expected, (list, tuple)) and isinstance(received, (list, tuple)):
|
|
return len(received) == len(expected) and all(
|
|
t_cmp(r, e) for r, e in zip(received, expected)
|
|
)
|
|
if isinstance(expected, dict) and isinstance(received, dict):
|
|
return received.keys() == expected.keys() and all(
|
|
t_cmp(received[k], expected[k]) for k in expected
|
|
)
|
|
if received is None or expected is None:
|
|
return received is None and expected is None
|
|
# Perl `eq` is a string comparison; stringify both sides.
|
|
return str(received) == str(expected)
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Requirement markers (need_*) -- thin wrappers over pytest.mark
|
|
# --------------------------------------------------------------------------- #
|
|
# Each marker records its requirement as marker args; the collection hook in
|
|
# conftest.py reads them against the probed HttpdInfo and skips as needed.
|
|
|
|
|
|
def need_module(*names: str) -> pytest.MarkDecorator:
|
|
"""Skip unless every named httpd module is available (need_module)."""
|
|
return pytest.mark.need_module(*names)
|
|
|
|
|
|
def need_min_apache_version(version: str) -> pytest.MarkDecorator:
|
|
"""Skip unless the server is at least ``version`` (need_min_apache_version)."""
|
|
return pytest.mark.need_min_apache_version(version)
|
|
|
|
|
|
def need_cgi() -> pytest.MarkDecorator:
|
|
"""Skip unless a CGI module (mod_cgi or mod_cgid) is available (need_cgi)."""
|
|
return pytest.mark.need_cgi()
|
|
|
|
|
|
def need_php() -> pytest.MarkDecorator:
|
|
"""Skip unless a PHP SAPI module is available (need_php)."""
|
|
return pytest.mark.need_php()
|
|
|
|
|
|
def need_ssl() -> pytest.MarkDecorator:
|
|
"""Skip unless mod_ssl is available (need_ssl)."""
|
|
return pytest.mark.need_ssl()
|
|
|
|
|
|
def need_lwp() -> pytest.MarkDecorator:
|
|
"""Always satisfied (the Perl need_lwp gated on the LWP client being present;
|
|
the Python client -- httpx -- is always available)."""
|
|
return pytest.mark.need_lwp()
|