Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/.coverage/
/.tmp/
/.git
/.git-blame-ignore
/.github
Expand Down
24 changes: 13 additions & 11 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ native IPv4/IPv6 support, private/whitelisted mode, and a management REST API.
- `docs/issues/` — Issue specs / implementation plans
- `share/default/` — Default configuration files and fixtures
- `storage/` — Runtime data (git-ignored); databases, logs, config
- `.tmp/` — Workspace-local temp dir (git-ignored); AI agent hook logs (`TORRUST_GIT_HOOKS_LOG_DIR=.tmp`)
and benchmark script cargo isolation dirs (`contrib/dev-tools/workflow-benchmarks/`)
- `.github/workflows/` — CI/CD workflows (testing, coverage, container, deployment)
- `.github/skills/` — Agent Skills for specialized workflows and task-specific guidance
- `.github/agents/` — Custom Copilot agents and their repository-specific definitions
Expand All @@ -61,29 +63,29 @@ All packages live under `packages/`. The workspace version is `3.0.0-develop`.
| Package | Crate Name | Prefix / Layer | Description |
| --------------------------------- | ------------------------------------------------- | -------------- | ---------------------------------------------- |
| `axum-health-check-api-server` | `torrust-tracker-axum-health-check-api-server` | `axum-*` | Health monitoring endpoint |
| `axum-http-server` | `torrust-tracker-axum-http-server` | `axum-*` | BitTorrent HTTP tracker server (BEP 3/23) |
| `axum-rest-api-server` | `torrust-tracker-axum-rest-api-server` | `axum-*` | Management REST API server |
| `axum-http-server` | `torrust-tracker-axum-http-server` | `axum-*` | BitTorrent HTTP tracker server (BEP 3/23) |
| `axum-rest-api-server` | `torrust-tracker-axum-rest-api-server` | `axum-*` | Management REST API server |
| `axum-server` | `torrust-tracker-axum-server` | `axum-*` | Base Axum HTTP server infrastructure |
| `clock` | `torrust-clock` | utilities | Mockable time source for deterministic testing |
| `configuration` | `torrust-tracker-configuration` | domain | Config file parsing, environment variables |
| `events` | `torrust-tracker-events` | domain | Domain event definitions |
| `http-protocol` | `torrust-tracker-http-tracker-protocol` | `*-protocol` | HTTP tracker protocol (BEP 3/23) parsing |
| `http-tracker-core` | `torrust-tracker-http-tracker-core` | `*-core` | HTTP-specific tracker domain logic |
| `http-protocol` | `torrust-tracker-http-tracker-protocol` | `*-protocol` | HTTP tracker protocol (BEP 3/23) parsing |
| `http-tracker-core` | `torrust-tracker-http-tracker-core` | `*-core` | HTTP-specific tracker domain logic |
| `located-error` | `torrust-located-error` | utilities | Diagnostic errors with source locations |
| `metrics` | `torrust-metrics` | domain | Prometheus metrics integration |
| `peer-id` | `bittorrent-peer-id` | domain | Peer ID parsing and formatting utilities |
| `primitives` | `torrust-tracker-primitives` | domain | Core domain types (InfoHash, PeerId, ...) |
| `rest-api-client` | `torrust-tracker-rest-api-client` | client tools | REST API client library |
| `rest-api-core` | `torrust-tracker-rest-api-core` | client tools | REST API core logic |
| `rest-api-client` | `torrust-tracker-rest-api-client` | client tools | REST API client library |
| `rest-api-core` | `torrust-tracker-rest-api-core` | client tools | REST API core logic |
| `server-lib` | `torrust-server-lib` | shared | Shared server library utilities |
| `swarm-coordination-registry` | `torrust-tracker-swarm-coordination-registry` | domain | Torrent/peer coordination registry |
| `test-helpers` | `torrust-tracker-test-helpers` | utilities | Mock servers, test data generation |
| `torrent-repository-benchmarking` | `torrust-tracker-torrent-repository-benchmarking` | benchmarking | Torrent storage benchmarks |
| `tracker-client` | `torrust-tracker-client` | client tools | CLI tracker interaction/testing client |
| `tracker-core` | `torrust-tracker-core` | `*-core` | Central tracker peer-management logic |
| `udp-protocol` | `torrust-tracker-udp-tracker-protocol` | `*-protocol` | UDP tracker protocol (BEP 15) framing/parsing |
| `udp-tracker-core` | `torrust-tracker-udp-tracker-core` | `*-core` | UDP-specific tracker domain logic |
| `udp-server` | `torrust-tracker-udp-server` | server | UDP tracker server implementation |
| `tracker-client` | `torrust-tracker-client` | client tools | CLI tracker interaction/testing client |
| `tracker-core` | `torrust-tracker-core` | `*-core` | Central tracker peer-management logic |
| `udp-protocol` | `torrust-tracker-udp-tracker-protocol` | `*-protocol` | UDP tracker protocol (BEP 15) framing/parsing |
| `udp-tracker-core` | `torrust-tracker-udp-tracker-core` | `*-core` | UDP-specific tracker domain logic |
| `udp-server` | `torrust-tracker-udp-server` | server | UDP tracker server implementation |

**Console tools** (under `console/`):

Expand Down
32 changes: 22 additions & 10 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@ RUN cargo binstall --no-confirm cargo-chef cargo-nextest
FROM docker.io/library/rust:slim-trixie AS tester
WORKDIR /tmp

RUN apt-get update; apt-get install -y curl sqlite3; apt-get autoclean
RUN apt-get update \
&& apt-get install -y curl sqlite3 time \
&& apt-get autoclean
RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash
RUN cargo binstall --no-confirm cargo-nextest
# Database initialization: Tests at runtime require a pre-initialized SQLite3 database
# to test against a valid (not corrupted) schema. The VACUUM command optimizes the
# database file layout. This image layer is inherited by test_debug and test stages.

COPY ./share/ /app/share/torrust
RUN mkdir -p /app/share/torrust/default/database/; \
sqlite3 /app/share/torrust/default/database/tracker.sqlite3.db "VACUUM;"
RUN time mkdir -p /app/share/torrust/default/database/ \
&& time sqlite3 /app/share/torrust/default/database/tracker.sqlite3.db "VACUUM;"

## Su Exe Compile
FROM docker.io/library/gcc:trixie AS gcc
COPY ./contrib/dev-tools/su-exec/ /usr/local/src/su-exec/
RUN cc -Wall -Werror -g /usr/local/src/su-exec/su-exec.c -o /usr/local/bin/su-exec; chmod +x /usr/local/bin/su-exec
RUN cc -Wall -Werror -g /usr/local/src/su-exec/su-exec.c -o /usr/local/bin/su-exec \
&& chmod +x /usr/local/bin/su-exec


## Chef Prepare (look at project and see wat we need)
Expand Down Expand Up @@ -80,9 +83,13 @@ COPY --from=build_debug \
RUN cargo nextest run --workspace-remap /test/src/ --extract-to /test/src/ --no-run --archive-file /test/torrust-tracker-debug.tar.zst
RUN cargo nextest run --workspace-remap /test/src/ --target-dir-remap /test/src/target/ --cargo-metadata /test/src/target/nextest/cargo-metadata.json --binaries-metadata /test/src/target/nextest/binaries-metadata.json

RUN mkdir -p /app/bin/; cp -l /test/src/target/debug/torrust-tracker /app/bin/torrust-tracker
RUN mkdir /app/lib/; cp -l $(realpath $(ldd /app/bin/torrust-tracker | grep "libz\.so\.1" | awk '{print $3}')) /app/lib/libz.so.1
RUN chown -R root:root /app; chmod -R u=rw,go=r,a+X /app; chmod -R a+x /app/bin
RUN time mkdir -p /app/bin/ \
&& time cp -l /test/src/target/debug/torrust-tracker /app/bin/torrust-tracker
RUN time mkdir /app/lib/ \
&& time cp -l $(realpath $(ldd /app/bin/torrust-tracker | grep "libz\.so\.1" | awk '{print $3}')) /app/lib/libz.so.1
RUN time chown -R root:root /app \
&& time chmod -R u=rw,go=r,a+X /app \
&& time chmod -R a+x /app/bin

# Extract and Test (release)
FROM tester AS test
Expand All @@ -94,9 +101,14 @@ COPY --from=build \
RUN cargo nextest run --workspace-remap /test/src/ --extract-to /test/src/ --no-run --archive-file /test/torrust-tracker.tar.zst
RUN cargo nextest run --workspace-remap /test/src/ --target-dir-remap /test/src/target/ --cargo-metadata /test/src/target/nextest/cargo-metadata.json --binaries-metadata /test/src/target/nextest/binaries-metadata.json

RUN mkdir -p /app/bin/; cp -l /test/src/target/release/torrust-tracker /app/bin/torrust-tracker; cp -l /test/src/target/release/http_health_check /app/bin/http_health_check
RUN mkdir -p /app/lib/; cp -l $(realpath $(ldd /app/bin/torrust-tracker | grep "libz\.so\.1" | awk '{print $3}')) /app/lib/libz.so.1
RUN chown -R root:root /app; chmod -R u=rw,go=r,a+X /app; chmod -R a+x /app/bin
RUN time mkdir -p /app/bin/ \
&& time cp -l /test/src/target/release/torrust-tracker /app/bin/torrust-tracker \
&& time cp -l /test/src/target/release/http_health_check /app/bin/http_health_check
RUN time mkdir -p /app/lib/ \
&& time cp -l $(realpath $(ldd /app/bin/torrust-tracker | grep "libz\.so\.1" | awk '{print $3}')) /app/lib/libz.so.1
RUN time chown -R root:root /app \
&& time chmod -R u=rw,go=r,a+X /app \
&& time chmod -R a+x /app/bin


## Runtime
Expand Down
111 changes: 111 additions & 0 deletions contrib/dev-tools/workflow-benchmarks/run-container-baseline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env bash
# run-container-baseline.sh
#
# semantic-links:
# related-artifacts:
# - docs/issues/open/1841-1840-workflow-performance-baseline-analysis/ISSUE.md
# - docs/issues/open/1841-1840-workflow-performance-baseline-analysis/benchmark-results-baseline.md
# - .github/workflows/container.yaml
#
# Reproducible baseline timing capture for container-workflow-equivalent steps.
# Mirrors .github/workflows/container.yaml (job: test, matrix: debug + release).
#
# The CI workflow runs debug and release in parallel (matrix strategy).
# This script runs them sequentially. Total CI wall time ≈ max(debug, release).
#
# Usage:
# ./contrib/dev-tools/workflow-benchmarks/run-container-baseline.sh [--cold]
#
# Options:
# --cold Clear Docker builder cache and remove the tracked local image
# before measuring, approximating a shared-runner first run.
# Omit to measure the warm (cached) case.
#
# Output:
# Structured timing lines on stdout and a dated log under:
# docs/issues/open/1841-1840-workflow-performance-baseline-analysis/evidence/
#
# Re-use after later optimisations:
# Run this script once --cold and once without --cold after each change and
# compare the evidence logs to quantify the improvement.

set -euo pipefail

COLD=false
for arg in "$@"; do
case "$arg" in
--cold) COLD=true ;;
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
esac
done

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
EVIDENCE_DIR="$REPO_ROOT/docs/issues/open/1841-1840-workflow-performance-baseline-analysis/evidence"
mkdir -p "$EVIDENCE_DIR"

RUN_TYPE="warm"
$COLD && RUN_TYPE="cold"

LOG="$EVIDENCE_DIR/container-baseline-$(date -u +%Y%m%dT%H%M%SZ)-${RUN_TYPE}.log"

time_phase() {
local scope="$1" name="$2"
shift 2
echo "[$scope] ${name}_start"
local t0 t1 rc
t0=$(date +%s)
set +e
"$@"
rc=$?
set -e
t1=$(date +%s)
echo "[$scope] ${name}_seconds=$((t1 - t0))"
Comment on lines +56 to +62

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid observation. For the purposes of this baseline (measuring multi-minute build phases), second resolution is sufficient and the 0s entries honestly reflect that the phase completed in under one second. Sub-second precision is noted as a future improvement. Switching to date +%s%N would break portability on macOS (BSD date has no %N), so it warrants its own decision when the need arises.

echo "[$scope] ${name}_exit_code=$rc"
return $rc
Comment thread
josecelano marked this conversation as resolved.
}

{
echo "[meta] start_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "[meta] workflow=container"
echo "[meta] run_type=${RUN_TYPE}"
echo "[meta] repo_root=${REPO_ROOT}"

if $COLD; then
echo "[cold] cache_reset_start"
docker builder prune -af >/dev/null
docker image rm -f torrust-tracker:local >/dev/null 2>&1 || true
echo "[cold] cache_reset_done"
fi

# --- debug target (first matrix entry) ---
# --progress plain writes per-layer step output to stdout so it is captured
# in the evidence log alongside the phase timing lines. Without this flag
# Docker (BuildKit) emits the interactive progress to stderr only.
time_phase "${RUN_TYPE}" build_debug \
docker build \
--progress plain \
--file "${REPO_ROOT}/Containerfile" \
--target debug \
--tag torrust-tracker:local \
"${REPO_ROOT}"

time_phase "${RUN_TYPE}" inspect_debug \
docker image inspect torrust-tracker:local

# --- release target (second matrix entry) ---
time_phase "${RUN_TYPE}" build_release \
docker build \
--progress plain \
--file "${REPO_ROOT}/Containerfile" \
--target release \
--tag torrust-tracker:local \
"${REPO_ROOT}"

time_phase "${RUN_TYPE}" inspect_release \
docker image inspect torrust-tracker:local

echo "[meta] end_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
} | tee "$LOG"

echo ""
echo "Evidence log: $LOG"
152 changes: 152 additions & 0 deletions contrib/dev-tools/workflow-benchmarks/run-testing-baseline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env bash
# run-testing-baseline.sh
#
# semantic-links:
# related-artifacts:
# - docs/issues/open/1841-1840-workflow-performance-baseline-analysis/ISSUE.md
# - docs/issues/open/1841-1840-workflow-performance-baseline-analysis/benchmark-results-baseline.md
# - .github/workflows/testing.yaml
#
# Reproducible baseline timing capture for testing-workflow-equivalent steps.
# Mirrors .github/workflows/testing.yaml (jobs: unit + docker-e2e).
#
# The CI workflow runs unit(nightly) + unit(stable) + docker-e2e in parallel.
# This script runs phases sequentially; CI wall time ≈ max(unit_stable, docker-e2e).
#
# Usage:
# ./contrib/dev-tools/workflow-benchmarks/run-testing-baseline.sh [--cold]
#
# Options:
# --cold Use isolated CARGO_HOME and target dir, and clear the Docker builder
# cache before measuring, approximating a shared-runner first run.
# Omit to use the default ~/.cargo and target/ (warm / incremental).
#
# Output:
# Structured timing lines on stdout and a dated log under:
# docs/issues/open/1841-1840-workflow-performance-baseline-analysis/evidence/
#
# Re-use after later optimisations:
# Run this script once --cold and once without --cold after each change and
# compare the evidence logs to quantify the improvement.

set -euo pipefail

COLD=false
for arg in "$@"; do
case "$arg" in
--cold) COLD=true ;;
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
esac
done

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
EVIDENCE_DIR="$REPO_ROOT/docs/issues/open/1841-1840-workflow-performance-baseline-analysis/evidence"
mkdir -p "$EVIDENCE_DIR"

RUN_TYPE="warm"
$COLD && RUN_TYPE="cold"

LOG="$EVIDENCE_DIR/testing-baseline-$(date -u +%Y%m%dT%H%M%SZ)-${RUN_TYPE}.log"

time_phase() {
local scope="$1" name="$2"
shift 2
echo "[$scope] ${name}_start"
local t0 t1 rc
t0=$(date +%s)
set +e
"$@"
rc=$?
set -e
t1=$(date +%s)
echo "[$scope] ${name}_seconds=$((t1 - t0))"
Comment on lines +51 to +62

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the corresponding comment on run-container-baseline.sh: for multi-minute build phases second resolution is adequate and the 0s entries are correct. Sub-second timing is noted as a future improvement (portability concern with date +%s%N on BSD/macOS).

echo "[$scope] ${name}_exit_code=$rc"
return $rc
}

{
echo "[meta] start_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "[meta] workflow=testing"
echo "[meta] run_type=${RUN_TYPE}"
echo "[meta] repo_root=${REPO_ROOT}"

if $COLD; then
TMP_HOME="${REPO_ROOT}/.tmp/workflow-benchmarks/cargo-home"
TMP_TARGET="${REPO_ROOT}/.tmp/workflow-benchmarks/target"
echo "[cold] cache_reset_start"
rm -rf "${TMP_HOME}" "${TMP_TARGET}"
mkdir -p "${TMP_HOME}" "${TMP_TARGET}"
docker builder prune -af >/dev/null
docker image rm -f torrust-tracker:e2e-local >/dev/null 2>&1 || true
export CARGO_HOME="${TMP_HOME}"
export CARGO_TARGET_DIR="${TMP_TARGET}"
echo "[cold] cache_reset_done"
echo "[meta] cargo_home=${TMP_HOME}"
echo "[meta] cargo_target_dir=${TMP_TARGET}"
fi

cd "${REPO_ROOT}"

# --- unit job (shared phases) ---
time_phase "${RUN_TYPE}" fetch \
cargo fetch --verbose

time_phase "${RUN_TYPE}" install_linter \
cargo install --locked \
--git https://github.com/torrust/torrust-linting \
--rev 70f84a29925b16a903110e494c9b8de519633a7f \
--bin linter

Comment thread
josecelano marked this conversation as resolved.
# nightly-only in CI; run unconditionally to measure time
time_phase "${RUN_TYPE}" format \
cargo fmt --check

time_phase "${RUN_TYPE}" lint \
linter all

time_phase "${RUN_TYPE}" test_docs \
cargo test --doc --workspace

time_phase "${RUN_TYPE}" test_unit \
cargo test --tests --benches --examples --workspace --all-targets --all-features

# --- docker-e2e job ---
time_phase "${RUN_TYPE}" docker_build_e2e \
docker build \
--file "${REPO_ROOT}/Containerfile" \
--target release \
--tag torrust-tracker:e2e-local \
"${REPO_ROOT}"

time_phase "${RUN_TYPE}" e2e_tracker \
cargo run --bin e2e_tests_runner -- \
--config-toml-path "./share/default/config/tracker.e2e.container.sqlite3.toml" \
--tracker-image "torrust-tracker:e2e-local" \
--skip-build

time_phase "${RUN_TYPE}" e2e_qbittorrent_sqlite \
cargo run --bin qbittorrent_e2e_runner -- \
--tracker-image "torrust-tracker:e2e-local" \
--skip-build \
--db-driver sqlite3 \
--timeout-seconds 600

time_phase "${RUN_TYPE}" e2e_qbittorrent_mysql \
cargo run --bin qbittorrent_e2e_runner -- \
--tracker-image "torrust-tracker:e2e-local" \
--skip-build \
--db-driver mysql \
--timeout-seconds 600

time_phase "${RUN_TYPE}" e2e_qbittorrent_postgresql \
cargo run --bin qbittorrent_e2e_runner -- \
--tracker-image "torrust-tracker:e2e-local" \
--skip-build \
--db-driver postgresql \
--timeout-seconds 600

echo "[meta] end_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
} | tee "$LOG"

echo ""
echo "Evidence log: $LOG"
3 changes: 2 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"repomix-output.xml",
"TEMP-*.md",
"mutants.out",
"mutants.out.old"
"mutants.out.old",
"docs/issues/**/evidence/*.html"
]
}
Loading
Loading