Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6e261fe
Add pytest replay test framework
Aug 13, 2026
34c1f36
Replace AuTest with pytest Uranium tests
Aug 13, 2026
bea33ce
Improve procedural Uranium test support
Aug 14, 2026
3147ddf
Complete pytest Uranium migration
Aug 15, 2026
47765b0
Refine pytest Uranium migration
Aug 17, 2026
d3ee7b1
Split Uranium service implementations
Aug 17, 2026
c792e99
Document Uranium framework architecture
Aug 17, 2026
00a7c0f
Consolidate Uranium replay manifests
Aug 18, 2026
02ea68b
Harden pytest Uranium migration
Aug 18, 2026
1595386
Fix Uranium failures after master rebase
Aug 19, 2026
35ca34f
Fix Uranium CI failure handling
Aug 19, 2026
1179457
Harden H3 Go client log check
Aug 20, 2026
bca733f
Copy slow-post certificates into runroot
Aug 20, 2026
ab1f137
Harden timing-sensitive Uranium tests
Aug 20, 2026
2805c19
Stabilize CMCD prefetch test
Aug 20, 2026
59e706d
Make Uranium expectations explicit
Aug 22, 2026
1b74991
Convert new master tests to Uranium
Aug 25, 2026
50a47ba
Convert port descriptor test to Uranium
Aug 25, 2026
05e3599
Support multiple Uranium container runtimes
Aug 28, 2026
b4d09c2
Convert new master AuTests to Uranium
Aug 31, 2026
01337b2
Improve Uranium developer usability
Aug 31, 2026
b8df5f2
Synchronize asynchronous Uranium checks
Aug 31, 2026
8b6dd2c
Track coalesced origin connections
Aug 31, 2026
cac32d5
Convert new master tests to Uranium
Sep 16, 2026
6af9ca9
Make Uranium sandboxes identifiable
Sep 16, 2026
5ac0ad7
Keep readable Uranium test sandboxes
Sep 16, 2026
8988b68
Preserve Uranium coverage after rebasing
Sep 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
32 changes: 14 additions & 18 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ trafficserver/
**Pattern discovery:**
- Search for similar functionality in existing code
- Check `include/ts/ts.h` for plugin API patterns
- Look at tests in `tests/gold_tests/` for usage examples
- Look at tests in `tests/uranium_tests/` for usage examples

### Code Organization

Expand Down Expand Up @@ -362,26 +362,22 @@ plugins/my_plugin/

**When adding new functionality:**
1. Check if unit tests exist in same directory (Catch2)
2. Add integration tests in `tests/gold_tests/` (autest)
3. Prefer `Test.ATSReplayTest()` with `replay.yaml` format (Proxy Verifier). If
`ATSReplayTest` doesn't fit, prefer organizing the test around a test class with
separate functions for configuring the servers, ATS, client, etc.
2. Add integration tests in `tests/uranium_tests/` (pytest Uranium).
3. Prefer direct Proxy Verifier `*.test.yaml` files with an `urtest` section.
If replay coverage does not fit, organize the test around a scenario class
with separate methods for configuring the servers, ATS, client, etc., and
an explicit `run()` entry point.
4. Test both success and error paths

### AuTest Process Lifetime in Code Reviews

- `StillRunningAfter` and `StillRunningBefore` are assertions about whether a
process is running at a test-run boundary. They do not keep processes alive,
extend their lifetime, or control teardown.
- Omitting an origin, DNS server, or ATS process from `tr.StillRunningAfter`
does not cause AuTest to stop it. Do not request adding a process to this
assertion on every run as a way to preserve it for later runs.
- A process created at `Test` scope and started with `StartBefore` can serve
multiple test runs without appearing in each run's `StillRunningAfter`.
Check the process scope, startup dependencies, and actual shutdown behavior
### Uranium Process Lifetime in Code Reviews

- Native scenarios explicitly start their services, while the `ats_factory`
and `services` fixtures own teardown after the test finishes.
- A started service can serve several scenario steps. Assertions do not
extend its lifetime or control teardown.
- Check fixture scope, explicit start/stop calls, and actual shutdown behavior
before reporting a lifetime bug; a missing assertion alone is not evidence.
- Consult the [AuTest TestRun API](https://autestsuite.bitbucket.io/API/testrun.html)
for the assertion and process-ordering semantics.
- Direct replay tests manage their processes through `ReplayTest.run()`.

## Configuration

Expand Down
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,10 @@ cmake-build-*
tests/env-test/
tests/proxy-verifier
tests/Pipfile.lock
tests/gold_tests/bigobj/check_ramp
tests/gold_tests/bigobj/push_request
tests/gold_tests/chunked_encoding/smuggle-client
tests/gold_tests/tls/ssl-post
tests/uranium_tests/bigobj/check_ramp
tests/uranium_tests/bigobj/push_request
tests/uranium_tests/chunked_encoding/smuggle-client
tests/uranium_tests/tls/ssl-post

src/iocore/cache/test_*
src/iocore/cache/unit_tests/var/trafficserver/cache.db
Expand Down
76 changes: 45 additions & 31 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ with a sophisticated plugin system.
**Key Technologies:**
- Language: C++20
- Build System: CMake (migrated from autotools in v10)
- Testing: Catch2 (unit tests) + AuTest Python framework (end-to-end tests)
- Testing: Catch2 unit tests plus pytest Uranium replay and native scenario tests
- Protocols: TLS, HTTP/1.1, HTTP/2, HTTP/3 (via Quiche)

## Project Structure

Core sources live in `src/` (for example `src/proxy`, `src/iocore`,
`src/traffic_server`). Public headers are in `include/`. Built-in plugins are
in `plugins/` and `plugins/experimental/`. End-to-end tests are in `tests/`,
especially `tests/gold_tests/`. Build system files are in `cmake/` plus the
in `plugins/` and `plugins/experimental/`. Uranium tests are in `tests/`,
especially `tests/uranium_tests/`. Build system files are in `cmake/` plus the
top-level `CMakeLists.txt`, and docs are in `doc/`. Third party libraries that
we include locally are in `lib/`.

Expand Down Expand Up @@ -80,63 +80,75 @@ Unit tests are built into executables. Find the test binary and run it directly:
./build/src/tscore/test_tscore
```

### End-to-End Tests (AuTest)
### Uranium Tests (pytest)

**Enable autests during configuration:**
**Enable Uranium tests during configuration:**
```bash
cmake -B build -DENABLE_AUTEST=ON
cmake -B build -DENABLE_URTEST=ON
cmake --build build
cmake --install build
```

**Run all autests:**
**Run all Uranium tests:**
```bash
cmake --build build -t autest
cmake --build build -t urtest
```

**Run specific test(s):**
```bash
cd build/tests
./autest.sh --sandbox /tmp/sbcodex --clean=none -f <test_name_without_test_py>
./urtest.sh -q -k <pytest_expression>
```

For example, to run `cache-auth.test.py`:
For example, to run items whose names contain `header_rewrite`:
```bash
./autest.sh --sandbox /tmp/sbcursor --clean=none -f cache-auth
./urtest.sh -q -k header_rewrite
```

To run multiple tests efficiently, pass the -j option.
Use pytest-xdist's `-n` option to run selected tests in parallel.

```bash
cd build/tests
./autest.sh -j4 --sandbox /tmp/sbcodex --clean=none -f 'header_rewrite*'
./urtest.sh -q -n 4 -k "header_rewrite or cache_control"
```

Most end-to-end test coverage is in `tests/gold_tests/`. The CI system uses the
Docker image `ci.trafficserver.apache.org/ats/fedora:43` (Fedora version updated
regularly).
Most Uranium test coverage is in `tests/uranium_tests/`. The CI system uses the
container image `ci.trafficserver.apache.org/ats/fedora:44` (Fedora version
updated regularly). The source-tree `tests/urtest.sh` defaults to this image,
using Apple container on macOS, Podman on Linux, or Docker as a fallback. It
runs directly instead when it detects that it is already inside a container or
the Fedora 44 test environment. Use `--run-in-container` or
`--no-run-in-container` to override.

### Writing Autests
### Writing Uranium Tests

**New tests should use the `Test.ATSReplayTest()` approach**, which references a
`replay.yaml` file that describes the test configuration and traffic patterns
using the Proxy Verifier format. This is simpler, more maintainable, and
parseable by tools.
**New tests should normally be direct pytest replay tests.** Name the Proxy
Verifier replay `<scenario>.test.yaml`; the file's `urtest` section describes
DNS, server, client, and ATS setup, and pytest collects it without a companion
`.test.py` wrapper. Run these with `cmake --build build -t urtest-replay`.

If `ATSReplayTest` is not a good fit (say, the test needs a custom client), then
If a direct replay test is not a good fit (say, the test needs a custom client), then
organize the test around a test class with member functions that configure any
servers, the ATS process, and the client. See
`tests/gold_tests/ats_probe/ats_probe.test.py` for an example of a test organized
around a test class.
`tests/uranium_tests/cache/test_host_down_range_recursion.py` for an example of a
test organized around a scenario class and an explicit `run()` entry point.

In autests, launch Python helpers with `{sys.executable}` rather than a
hardcoded `python3`, so the test runs under the same interpreter the harness
uses.
In native tests, launch Python helpers with `sys.executable` rather than a
hardcoded `python3`, so the helper uses the same interpreter as pytest.

**For complete details on writing autests, see:**
- `doc/developer-guide/testing/autests.en.rst` - Comprehensive guide to autest
Tests that are useful only when explicitly requested, such as privileged, very
slow, or known-flaky diagnostic scenarios, use `@pytest.mark.manual`. Direct
replay tests set `urtest.manual` to `true` or a reason string. They are skipped
during normal runs. Enable them explicitly with `--run-manual` and normally
select the intended test with `-k`:

```bash
./urtest.sh --run-manual -k ats_probe
```

**For complete details on writing Uranium tests, see:**
- `doc/developer-guide/testing/uranium-tests.en.rst` - Comprehensive Uranium test guide
- Proxy Verifier format: https://github.com/yahoo/proxy-verifier
- AuTest framework: https://autestsuite.bitbucket.io/

## Development Workflow

Expand Down Expand Up @@ -372,6 +384,9 @@ MIOBuffer *buffer = (MIOBuffer*)malloc(sizeof(MIOBuffer));
- Python 3.11+ with proper type annotations
- 4-space indentation, never TABs
- Type annotations on all function signatures
- Document every parameter in a function docstring with `:param <name>:`.
Include units and other constraints that are not evident from the type, such
as documenting timeout values in seconds.
- Prefer f-strings over `str.format()` when building command lines, config lines,
and `Testers` expressions.

Expand Down Expand Up @@ -410,5 +425,4 @@ scope, and vulnerability reporting process.
- Official docs: https://trafficserver.apache.org/
- Developer wiki: https://cwiki.apache.org/confluence/display/TS/
- CI dashboard: https://ci.trafficserver.apache.org/
- AuTest framework: https://autestsuite.bitbucket.io/
- Proxy Verifier: https://github.com/yahoo/proxy-verifier
37 changes: 22 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,11 @@ option(ENABLE_DISK_FAILURE_TESTS "Build disk failure tests (enables AIO fault in
if(ENABLE_DISK_FAILURE_TESTS)
add_compile_definitions("AIO_FAULT_INJECTION")
endif()
option(ENABLE_AUTEST "Setup autest (default OFF)")
option(ENABLE_AUTEST_UDS "Setup autest with curl using UDS (default OFF)")
option(ENABLE_URTEST "Set up Uranium tests (default OFF)")
option(ENABLE_URTEST_UDS "Set up Uranium tests with curl using UDS (default OFF)")
if(DEFINED ENABLE_AUTEST OR DEFINED ENABLE_AUTEST_UDS)
message(FATAL_ERROR "ENABLE_AUTEST and ENABLE_AUTEST_UDS were removed; use ENABLE_URTEST and ENABLE_URTEST_UDS")
endif()
option(ENABLE_BENCHMARKS "Build benchmarks (default OFF)")
option(EXTERNAL_YAML_CPP "Use external yaml-cpp (default OFF)")
option(EXTERNAL_LIBSWOC "Use external libswoc (default OFF)")
Expand Down Expand Up @@ -818,7 +821,7 @@ check_struct_has_member("struct mptcp_info" mptcpi_subflows "linux/mptcp.h" HAVE
# find resolv library if available
find_package(resolv)

if(ENABLE_DOCS OR ENABLE_AUTEST)
if(ENABLE_DOCS OR ENABLE_URTEST)
find_package(Python3 REQUIRED)
find_program(UV uv REQUIRED)
find_program(NETCAT_PROGRAM nc REQUIRED)
Expand All @@ -834,27 +837,31 @@ if(ENABLE_DOCS)
find_program(GRAPHVIZ_DOT dot REQUIRED)
endif()

if(ENABLE_AUTEST)
if(ENABLE_URTEST)
# Default the sandbox to /tmp to keep paths short. Unix domain socket paths
# are limited to 108 characters and deep build directories (e.g. in home
# directories) can exceed this limit, causing confusing test failures. A hash
# of CMAKE_BINARY_DIR provides per-build isolation while keeping the path
# deterministic across runs.
string(MD5 _build_dir_hash "${CMAKE_BINARY_DIR}")
string(SUBSTRING "${_build_dir_hash}" 0 8 _build_dir_hash)
set(AUTEST_SANDBOX
"/tmp/sb_${_build_dir_hash}"
CACHE STRING "Location for autest output (default /tmp/sb_<hash>)"
set(URTEST_SANDBOX
"/tmp/urtest_${_build_dir_hash}"
CACHE STRING "Location for Uranium test output (default /tmp/urtest_<hash>)"
)
set(AUTEST_OPTIONS
set(URTEST_OPTIONS
""
CACHE STRING "Additional options for autest (default \"\")"
CACHE STRING "Additional options for Uranium tests (default \"\")"
)
if(DEFINED AUTEST_SANDBOX
OR DEFINED AUTEST_OPTIONS
OR DEFINED PYTEST_OPTIONS
)
# Also create AUTEST_OPTIONS_LIST from the string for use in cmake targets.
# This prevents cmake from escaping spaces in the arguments, which confuses
# the autest command. The original AUTEST_OPTIONS string is used in the
# autest.sh script.
separate_arguments(AUTEST_OPTIONS_LIST UNIX_COMMAND "${AUTEST_OPTIONS}")
message(
FATAL_ERROR
"AUTEST_SANDBOX, AUTEST_OPTIONS, and PYTEST_OPTIONS were removed; use URTEST_SANDBOX and URTEST_OPTIONS"
)
endif()
file(READ "${CMAKE_SOURCE_DIR}/tests/proxy-verifier-version.txt" PROXY_VERIFIER_VERSION)
string(STRIP "${PROXY_VERIFIER_VERSION}" PROXY_VERIFIER_VERSION)
file(READ "${CMAKE_SOURCE_DIR}/tests/proxy-verifier-checksum.txt" PROXY_VERIFIER_SHA1)
Expand Down Expand Up @@ -974,7 +981,7 @@ add_subdirectory(src/traffic_via)
if(ENABLE_CRIPTS)
add_subdirectory(src/cripts)
endif()
if(ENABLE_AUTEST)
if(ENABLE_URTEST)
add_subdirectory(tests)
endif()
if(ENABLE_FUZZING)
Expand Down
Loading