version_compatibility.py creates a fresh disposable commit-server installation
for every selected release/platform pair. The required matrix is P4 2023.1,
2023.2, 2024.1, 2024.2, 2025.1, 2025.2 and 2026.1 on UBI 8.10 and 9.8.
These release lines come from the vendor's server schema release table.
Each cell downloads its own matching p4, p4d, broker and proxy binaries and
verifies their hashes against that release's vendor SHA256SUMS, for example
2023.1 x86_64
and 2026.1 ARM64.
The exact patch builds, checksums and immutable image IDs are recorded with the
results; this does not test every earlier patch build in a release line.
The runner refuses an existing container. Every cell invokes the actual
reset.sh, mkdirs.sh and generated mkdirs.cfg with an empty database. It does
not downgrade populated databases or rehearse an existing-install migration.
Its distro Python 3.12 virtual environment and P4Python are separately labeled;
this compatibility matrix does not replace the main source-built Python matrix.
The journal is /p4/1/journals/journal, storage is local, mail is disabled, and
all server endpoints are confined to their container's loopback interface.
The temporary restored-database probes disable journaling with -J off while
comparing data; every installed live server retains the required journal path.
Their scratch database is removed only after the daemon has exited. A failed
stop or shutdown timeout fails the scenario and retains that scratch directory
inside the stopped test container for inspection.
Each cell must pass all eight named scenarios:
| Scenario | Required behavior |
|---|---|
clean_install |
Real clean SDP installation, version-matched binaries and systemd startup |
service_user_authentication |
Create a native service user, initialize its password under server policy, authenticate and perform a real read |
exact_fixture |
Independently known text/binary revision bytes, edit/delete/move history, shelf contents and label/client/group specifications |
restart_preserves_data |
Installed service restart preserves that exact fixture |
checkpoint_restore |
SDP checkpoint/restore is served separately and its fixture is compared with the original |
journal_rotation_restore |
A later submitted file and counter survive journal rotation and replay |
maintenance_queries |
Real inactivity queries, complete path inventory and limit-zero client selection preserve fixture data |
sendq_cleanup |
Real local configuration scope/identity/path selection, service-down enforcement, dedicated queue cleanup and exact shared partitioned-client have preservation |
The cleanup scenario runs the same twenty-four named subcases as the current-server
matrix. These cover unset/empty, global/local/other-server settings, relative and
absolute paths, root symlinks, missing/non-directory targets, P4NAME environment
and database redirects, -In precedence, and running-server refusal. Shared
readonly overlap in either direction, or a readonly path traversing queue
symlinks (including a chain whose configured path starts outside the queue),
must preserve every required alias, actual persistent tables and synced
partitioned-client have revisions. A queue containing an alias required by the
configured database root or by the queue path itself must be refused without
removing any queue entries. Queue cleanup runs only while the
installed service is stopped; configuration is restored before the next scenario.
Missing binaries, setup failures, failed capabilities, missing scenarios or missing
matrix cells fail acceptance. A failed prerequisite blocks later dependent
scenarios and remains a failed cell. Stopped containers and logs are retained for
inspection; remove only explicitly named test containers after reviewing results.
Older servers can lack the p4 diskspace features used by installer safety
checks. The report counts and exposes these skipped checks in capability_gaps;
passing the data scenarios does not claim that those safety checks ran.
Version-gated configurable omissions are recorded there individually with their
required and running server versions. Applicable settings must still succeed.
Unexpected configuration errors still fail the installation cell, even if the
installer exits successfully after logging a warning.
Build the regular UBI images with the main matrix runner. On an ARM
host, releases 2023.1 and 2023.2 require x86_64 emulation: their vendor ARM64 binary
directories are absent. A working Linux binfmt emulator is a prerequisite; record
it with the results and do not describe emulated tests as native x86 coverage.
Build the two x86 package images using the existing definitions:
docker build --platform linux/amd64 -f sdp/test/containers/Dockerfile.rhel8 -t sdp-assurance-rhel8-amd64:8.10 sdp/test/containers
docker build --platform linux/amd64 -f sdp/test/containers/Dockerfile.rhel9 -t sdp-assurance-rhel9-amd64:9.8 sdp/test/containers
Derive the historical images before starting containers. This masks
systemd-binfmt.service inside these disposable images, preventing a container
boot from resetting the dedicated VM's emulator registration. For each base/tag
pair below, run:
docker build --build-arg BASE_IMAGE= -f sdp/test/containers/Dockerfile.versions -t sdp/test/containers
| Base | Tag |
|---|---|
sdp-assurance-rhel8:8.10 |
sdp-version-rhel8:8.10 |
sdp-assurance-rhel9:9.8 |
sdp-version-rhel9:9.8 |
sdp-assurance-rhel8-amd64:8.10 |
sdp-version-rhel8-amd64:8.10 |
sdp-assurance-rhel9-amd64:9.8 |
sdp-version-rhel9-amd64:9.8 |
For the last two derived builds, add --platform linux/amd64. The runner pins the
resolved image ID. It does not mount host directories, publish ports or expose
credentials. The containers run privileged only inside the dedicated test VM.
python3 sdp/test/containers/version_compatibility.py \
--source /absolute/path/to/verified-source-export \
--results /absolute/path/to/new-version-results \
--name-prefix sdp-version-unique-run --jobs 2
A single-cell development run can add --release 2023.1 --platform rhel8.
--jobs defaults to one and permits at most two independent cells. Each uses its
own fresh container and result directory. Incremental reports retain every
completed cell, and the final report always orders cells by release and platform,
regardless of completion order. A tooling failure remains a failed cell while
other cells finish.
Within one runner, container startup/readiness and shutdown are serialized while
provisioning and the test scenarios remain parallel. This avoids overlapping
privileged systemd lifecycle operations; it does not diagnose or guarantee a fix
for emulator startup failures. Coordinate other runners' container shutdowns and
starts separately when investigating such failures.
Systemd readiness has a 180-second deadline, longer than the images' normal
90-second unit-start timeout. Only running or degraded states are accepted;
initializing and other unfinished states fail at the deadline. A failed boot
retains container inspection, console, manager state, pending jobs and failed-unit
diagnostics before shutdown.
The final release gate still requires all fourteen cells. Do not merge cells from
different source exports. version-compatibility.json identifies the exact source
manifest; each subdirectory retains installation configuration, vendor provenance,
worker assertions, server logs and its case.json.
These fixtures establish specific release compatibility, not production-scale throughput, every historical role combination, network filesystem semantics, upgrade safety or behavior across an entire fleet. Review any failed or blocked cell before expanding the supported claim.
# P4 server release compatibility `version_compatibility.py` creates a fresh disposable commit-server installation for every selected release/platform pair. The required matrix is P4 **2023.1, 2023.2, 2024.1, 2024.2, 2025.1, 2025.2 and 2026.1** on UBI **8.10 and 9.8**. These release lines come from the vendor's [server schema release table](https://help.perforce.com/helix-core/server-apps/schema/current/). Each cell downloads its own matching `p4`, `p4d`, broker and proxy binaries and verifies their hashes against that release's vendor `SHA256SUMS`, for example [2023.1 x86_64](https://ftp.perforce.com/perforce/r23.1/bin.linux26x86_64/SHA256SUMS) and [2026.1 ARM64](https://ftp.perforce.com/perforce/r26.1/bin.linux26aarch64/SHA256SUMS). The exact patch builds, checksums and immutable image IDs are recorded with the results; this does not test every earlier patch build in a release line. The runner refuses an existing container. Every cell invokes the actual `reset.sh`, `mkdirs.sh` and generated `mkdirs.cfg` with an empty database. It does not downgrade populated databases or rehearse an existing-install migration. Its distro Python 3.12 virtual environment and P4Python are separately labeled; this compatibility matrix does not replace the main source-built Python matrix. The journal is `/p4/1/journals/journal`, storage is local, mail is disabled, and all server endpoints are confined to their container's loopback interface. The temporary restored-database probes disable journaling with `-J off` while comparing data; every installed live server retains the required journal path. Their scratch database is removed only after the daemon has exited. A failed stop or shutdown timeout fails the scenario and retains that scratch directory inside the stopped test container for inspection. Each cell must pass all eight named scenarios: | Scenario | Required behavior | | --- | --- | | `clean_install` | Real clean SDP installation, version-matched binaries and systemd startup | | `service_user_authentication` | Create a native service user, initialize its password under server policy, authenticate and perform a real read | | `exact_fixture` | Independently known text/binary revision bytes, edit/delete/move history, shelf contents and label/client/group specifications | | `restart_preserves_data` | Installed service restart preserves that exact fixture | | `checkpoint_restore` | SDP checkpoint/restore is served separately and its fixture is compared with the original | | `journal_rotation_restore` | A later submitted file and counter survive journal rotation and replay | | `maintenance_queries` | Real inactivity queries, complete path inventory and limit-zero client selection preserve fixture data | | `sendq_cleanup` | Real local configuration scope/identity/path selection, service-down enforcement, dedicated queue cleanup and exact shared partitioned-client have preservation | The cleanup scenario runs the same twenty-four named subcases as the current-server matrix. These cover unset/empty, global/local/other-server settings, relative and absolute paths, root symlinks, missing/non-directory targets, P4NAME environment and database redirects, `-In` precedence, and running-server refusal. Shared readonly overlap in either direction, or a readonly path traversing queue symlinks (including a chain whose configured path starts outside the queue), must preserve every required alias, actual persistent tables and synced partitioned-client have revisions. A queue containing an alias required by the configured database root or by the queue path itself must be refused without removing any queue entries. Queue cleanup runs only while the installed service is stopped; configuration is restored before the next scenario. Missing binaries, setup failures, failed capabilities, missing scenarios or missing matrix cells fail acceptance. A failed prerequisite blocks later dependent scenarios and remains a failed cell. Stopped containers and logs are retained for inspection; remove only explicitly named test containers after reviewing results. Older servers can lack the `p4 diskspace` features used by installer safety checks. The report counts and exposes these skipped checks in `capability_gaps`; passing the data scenarios does not claim that those safety checks ran. Version-gated configurable omissions are recorded there individually with their required and running server versions. Applicable settings must still succeed. Unexpected configuration errors still fail the installation cell, even if the installer exits successfully after logging a warning. ## Images and execution Build the regular UBI images with the [main matrix runner](README.md). On an ARM host, releases 2023.1 and 2023.2 require x86_64 emulation: their vendor ARM64 binary directories are absent. A working Linux `binfmt` emulator is a prerequisite; record it with the results and do not describe emulated tests as native x86 coverage. Build the two x86 package images using the existing definitions: ```bash docker build --platform linux/amd64 -f sdp/test/containers/Dockerfile.rhel8 -t sdp-assurance-rhel8-amd64:8.10 sdp/test/containers docker build --platform linux/amd64 -f sdp/test/containers/Dockerfile.rhel9 -t sdp-assurance-rhel9-amd64:9.8 sdp/test/containers ``` Derive the historical images before starting containers. This masks `systemd-binfmt.service` inside these disposable images, preventing a container boot from resetting the dedicated VM's emulator registration. For each base/tag pair below, run: ```bash docker build --build-arg BASE_IMAGE=<base> -f sdp/test/containers/Dockerfile.versions -t <tag> sdp/test/containers ``` | Base | Tag | | --- | --- | | `sdp-assurance-rhel8:8.10` | `sdp-version-rhel8:8.10` | | `sdp-assurance-rhel9:9.8` | `sdp-version-rhel9:9.8` | | `sdp-assurance-rhel8-amd64:8.10` | `sdp-version-rhel8-amd64:8.10` | | `sdp-assurance-rhel9-amd64:9.8` | `sdp-version-rhel9-amd64:9.8` | For the last two derived builds, add `--platform linux/amd64`. The runner pins the resolved image ID. It does not mount host directories, publish ports or expose credentials. The containers run privileged only inside the dedicated test VM. ```bash python3 sdp/test/containers/version_compatibility.py \ --source /absolute/path/to/verified-source-export \ --results /absolute/path/to/new-version-results \ --name-prefix sdp-version-unique-run --jobs 2 ``` A single-cell development run can add `--release 2023.1 --platform rhel8`. `--jobs` defaults to one and permits at most two independent cells. Each uses its own fresh container and result directory. Incremental reports retain every completed cell, and the final report always orders cells by release and platform, regardless of completion order. A tooling failure remains a failed cell while other cells finish. Within one runner, container startup/readiness and shutdown are serialized while provisioning and the test scenarios remain parallel. This avoids overlapping privileged systemd lifecycle operations; it does not diagnose or guarantee a fix for emulator startup failures. Coordinate other runners' container shutdowns and starts separately when investigating such failures. Systemd readiness has a 180-second deadline, longer than the images' normal 90-second unit-start timeout. Only `running` or `degraded` states are accepted; `initializing` and other unfinished states fail at the deadline. A failed boot retains container inspection, console, manager state, pending jobs and failed-unit diagnostics before shutdown. The final release gate still requires all fourteen cells. Do not merge cells from different source exports. `version-compatibility.json` identifies the exact source manifest; each subdirectory retains installation configuration, vendor provenance, worker assertions, server logs and its `case.json`. These fixtures establish specific release compatibility, not production-scale throughput, every historical role combination, network filesystem semantics, upgrade safety or behavior across an entire fleet. Review any failed or blocked cell before expanding the supported claim.
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #2 | 34011 | Russell C. Jackson (Rusty) |
Reduce checkpoint thread defaults to 16, tolerate missing journal numbers, and clean dedicated send queues during stopped database recreation. Resolve client.sendq.dir and client.readonly.dir from the local database with the effective server identity. Preserve all shared readonly storage with a warning, protect database and journal paths, and clean both database roots while stopped. Correct readonly configuration lookup and nested copy destinations. Preserve journal archival thresholds, intentional server.locks removal, and existing shell modes. Update operational documentation and regression coverage. Validation passed on the exact source manifest: 44 platform stages, 30 topology scenarios, 112 historical scenarios across p4d 2023.1-2026.1 on UBI 8/9, 70 focused tests on each of Bash 3.2/5.3, and the combined release gate. RHEL tests use UBI containers; historical 2023 releases use x86 emulation. |
||
| #1 | 34004 | Russell C. Jackson (Rusty) |
Improve SDP backup/recovery, Maintenance, logging and cloud operation. Add owned checkpoint locks, recovery-aware retention, preserved database switches, bounded cleanup and coordinated AWS/Azure snapshots. Fix service-user password initialization, edge staging, standby promotion state parsing, proxy cache setup, typed depot verification and historical-server configuration/error handling. Remove unused OTP programs; keep Windows removed, server.locks cleanup and the journal-count condition unchanged. Add no global shell strict modes. Update operational documentation and add reproducible mkdirs.sh/mkdirs.cfg container assurance. Validate Ubuntu 26.04 and UBI 8.10/9.8/10.2 across both Python runtimes: 44 stages; 428 offline tests per runtime/OS, zero offline skips; 19 deployed-archive comparisons per combination. Three six-node topology runs pass all 30 recovery/failure scenarios. P4D 2023.1 through 2026.1 on UBI 8/9 pass all 14 cells and 98 scenarios. Static, documentation and provenance checks pass. Containers do not certify every fleet kernel, patch build or integration. Tested source manifest SHA-256: e1a23e17b8ced8c1148d9a250589977c6f6e98606bf2a81dc3ff5d7c909e3695 Deployed comparison archive SHA-256: 1bd23217356ee3808e040d39aea5be9519bda7c8f2b4924656a70aff8ad7293a |