Skip to content

Conversation

@echobt
Copy link
Contributor

@echobt echobt commented Feb 5, 2026

Summary

Add comprehensive test suite and Docker configuration for testing multi-validator P2P networks locally.

Changes

Bug Fixes

  • Fixed Docker healthchecks to use test -e instead of test -f since distributed.db is a directory (sled database), not a file

New Features

  • Added docker-compose.multi-validator.yml for spinning up a 4-validator test network
  • Added Dockerfile.test-validator for lightweight test builds
  • Added test-comprehensive.sh script for running the full test suite
  • Added entrypoint-test.sh for configuring test validators

Testing

All tests pass:

  • Workspace unit tests: 400+ tests passing
  • Docker integration tests: 4 tests passing (broker lifecycle, security policies)
  • Bittensor integration tests: 2 tests passing (testnet connection, metagraph sync)
  • Multi-validator Docker network: 4 validators running and healthy with synchronized state

Local Testing Instructions

# Run unit tests
cargo test --workspace --release

# Run multi-validator Docker test
docker compose -f tests/docker/docker-compose.multi-validator.yml up -d
docker ps -a --filter "name=platform-validator"
docker compose -f tests/docker/docker-compose.multi-validator.yml down -v

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved healthcheck validation to detect any filesystem entry type, not just regular files.
  • Chores

    • Added comprehensive test suite orchestration with multi-phase testing across build, unit tests, integration tests, security policies, P2P consensus, and storage modules.
    • Introduced multi-validator test network infrastructure for testing distributed validator scenarios.
    • Added test validator container and entrypoint configuration for environment-driven validator initialization.

Add comprehensive test suite and Docker configuration for testing
multi-validator P2P networks locally:
- docker-compose.multi-validator.yml for 4-validator test network
- Dockerfile.test-validator for lightweight test builds
- test-comprehensive.sh for running full test suite
- entrypoint-test.sh for configuring test validators
@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

📝 Walkthrough

Walkthrough

These changes introduce comprehensive testing infrastructure for a multi-validator test network. Minor healthcheck updates adjust file existence checks, while new Docker configurations define a test validator image and multi-node network topology. A new comprehensive test script orchestrates seven sequential test phases across the Rust workspace.

Changes

Cohort / File(s) Summary
Healthcheck Updates
Dockerfile, docker-compose.yml
Changed existence check from test -f (regular files only) to test -e (any filesystem entry).
Test Infrastructure
scripts/test-comprehensive.sh
New Bash script orchestrating platform-wide test suite across seven phases: build, unit tests, Docker integration tests, Bittensor integration tests, security policy tests, P2P consensus tests, and storage tests. Includes colored logging, phase-based error handling, timeout management for network tests, and a summary report with pass/fail/skip counts.
Test Validator Docker Setup
tests/docker/Dockerfile.test-validator, tests/docker/entrypoint-test.sh
New multi-stage Dockerfile building a validator-node binary from Rust source and runtime image from Debian. Companion entrypoint script constructs validator arguments from environment variables (secret key, network ID, bootstrap peers, bittensor flag).
Multi-Validator Test Network
tests/docker/docker-compose.multi-validator.yml
New Docker Compose configuration deploying four validator services (validator-1 through validator-4) with distinct seeds, environment variables, dedicated volumes, fixed IPv4 addresses on a bridge network, startup dependencies, and healthchecks.

Sequence Diagram

sequenceDiagram
    participant Build as Build System
    participant UnitTests as Unit Tests
    participant DockerInt as Docker Integration
    participant Bittensor as Bittensor Tests
    participant Security as Security Tests
    participant P2P as P2P Tests
    participant Storage as Storage Tests
    participant Summary as Summary Report

    Build->>Build: cargo build --release
    Build-->>UnitTests: ✓ Build Success

    UnitTests->>UnitTests: cargo test --workspace --release
    UnitTests-->>DockerInt: ✓ Unit Tests Complete

    DockerInt->>DockerInt: Check Docker daemon
    DockerInt->>DockerInt: cargo test secure-container-runtime
    DockerInt->>DockerInt: cargo test challenge-orchestrator
    DockerInt-->>Bittensor: ✓ Docker Tests Complete

    Bittensor->>Bittensor: cargo test platform-bittensor (120s timeout)
    Bittensor-->>Security: ✓ Bittensor Tests Complete

    Security->>Security: test_default_policy_blocks_docker_socket
    Security->>Security: test_strict_policy_blocks_non_whitelisted_images
    Security->>Security: test_policy_enforces_resource_limits
    Security-->>P2P: ✓ Security Tests Complete

    P2P->>P2P: cargo test platform-p2p-consensus
    P2P-->>Storage: ✓ P2P Tests Complete

    Storage->>Storage: cargo test platform-storage
    Storage->>Storage: cargo test platform-distributed-storage
    Storage-->>Summary: ✓ Storage Tests Complete

    Summary->>Summary: Calculate pass/fail/skip counts
    Summary->>Summary: Print colored summary
    Summary-->>Storage: Exit with status code
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 A hop through tests so grand and true,
Seven phases marching, tried and new,
Validators dance on networks spun,
Docker stages built, compiling fun—
From build to bloom, our code runs free! 🚀

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding multi-validator test infrastructure and fixing healthchecks from test -f to test -e for directory detection.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch test/multi-validator-docker-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@scripts/test-comprehensive.sh`:
- Around line 17-18: The script currently uses "set -e" but misses "set -o
pipefail", so failures in piped commands like the "cargo test ... | tee ..."
pipelines (used around the cargo test checks) can be masked by tee's success;
add "set -o pipefail" immediately after the existing "set -e" in
scripts/test-comprehensive.sh so that pipeline failures (e.g., in the cargo test
| tee pipelines) correctly propagate non-zero exit codes to the script's
conditionals and cause test failures to be detected.

In `@tests/docker/entrypoint-test.sh`:
- Around line 10-35: The script builds command args into a single string
variable ARGS and then calls exec validator-node $ARGS which causes
word-splitting, glob expansion and drops any extra script args; change to use a
bash array (e.g., args_array) and append elements (like "--data-dir",
"${DATA_DIR:-/data}", "--listen-addr",
"${P2P_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/9000}", conditional pushes for SECRET_KEY,
NETUID, each bootstrap peer, and "--no-bittensor") and finally append "$@"
before calling exec validator-node "${args_array[@]}" so arguments are preserved
and not split by the shell.

Comment on lines +17 to +18
set -e

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and examine its structure
git ls-files | grep -E "scripts/test-comprehensive\.sh"

Repository: PlatformNetwork/platform-v2

Length of output: 100


🏁 Script executed:

# Read the file to verify the lines mentioned
wc -l scripts/test-comprehensive.sh

Repository: PlatformNetwork/platform-v2

Length of output: 104


🏁 Script executed:

# Read the relevant sections of the file
cat -n scripts/test-comprehensive.sh | sed -n '1,30p'

Repository: PlatformNetwork/platform-v2

Length of output: 1038


🏁 Script executed:

# Check the pipeline sections at the mentioned lines
cat -n scripts/test-comprehensive.sh | sed -n '85,95p'

Repository: PlatformNetwork/platform-v2

Length of output: 592


🏁 Script executed:

# Check around line 109
cat -n scripts/test-comprehensive.sh | sed -n '105,115p'

Repository: PlatformNetwork/platform-v2

Length of output: 597


🏁 Script executed:

# Check around line 184
cat -n scripts/test-comprehensive.sh | sed -n '180,190p'

Repository: PlatformNetwork/platform-v2

Length of output: 580


🏁 Script executed:

# Search for pipefail in the file
grep -n "pipefail" scripts/test-comprehensive.sh || echo "No pipefail found"

Repository: PlatformNetwork/platform-v2

Length of output: 88


Enable pipefail to prevent masked test failures in piped commands.

The pipelines at lines 88, 109, and 184 use cargo test ... | tee ... in if conditions without set -o pipefail. This causes test failures to be masked since the exit code comes from tee (which succeeds) rather than cargo test, allowing failed tests to incorrectly pass the conditional checks.

🔧 Proposed fix
 set -e
+set -o pipefail

Add set -o pipefail after line 17 to properly propagate exit codes through pipelines.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
set -e
set -e
set -o pipefail
🤖 Prompt for AI Agents
In `@scripts/test-comprehensive.sh` around lines 17 - 18, The script currently
uses "set -e" but misses "set -o pipefail", so failures in piped commands like
the "cargo test ... | tee ..." pipelines (used around the cargo test checks) can
be masked by tee's success; add "set -o pipefail" immediately after the existing
"set -e" in scripts/test-comprehensive.sh so that pipeline failures (e.g., in
the cargo test | tee pipelines) correctly propagate non-zero exit codes to the
script's conditionals and cause test failures to be detected.

Comment on lines +10 to +35
# Build command arguments
ARGS="--data-dir ${DATA_DIR:-/data}"
ARGS="$ARGS --listen-addr ${P2P_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/9000}"

if [ -n "$VALIDATOR_SECRET_KEY" ]; then
ARGS="$ARGS --secret-key $VALIDATOR_SECRET_KEY"
fi

if [ -n "$NETUID" ]; then
ARGS="$ARGS --netuid $NETUID"
fi

if [ -n "$BOOTSTRAP_PEERS" ]; then
# Split by comma and add each peer
IFS=',' read -ra PEERS <<< "$BOOTSTRAP_PEERS"
for peer in "${PEERS[@]}"; do
ARGS="$ARGS --bootstrap $peer"
done
fi

if [ "$NO_BITTENSOR" = "true" ]; then
ARGS="$ARGS --no-bittensor"
fi

echo "Starting validator-node with args: $ARGS"
exec validator-node $ARGS
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, locate the file
fd -type f -name "entrypoint-test.sh" 2>/dev/null | head -20

Repository: PlatformNetwork/platform-v2

Length of output: 53


🏁 Script executed:

# Check if the file exists and examine the relevant lines
if [ -f "tests/docker/entrypoint-test.sh" ]; then
  cat -n "tests/docker/entrypoint-test.sh" | head -40
fi

Repository: PlatformNetwork/platform-v2

Length of output: 1326


🏁 Script executed:

# Also check the shebang and structure
head -5 "tests/docker/entrypoint-test.sh" 2>/dev/null || echo "File not found"

Repository: PlatformNetwork/platform-v2

Length of output: 341


Use array-based argument handling to prevent word-splitting and preserve extra args.
Lines 11–35 build ARGS as a string and execute it unquoted on line 35 (exec validator-node $ARGS). This causes word-splitting and pathname expansion, and ignores $@, dropping any extra arguments passed to the script. Use an array and append "$@":

🔧 Proposed fix
-ARGS="--data-dir ${DATA_DIR:-/data}"
-ARGS="$ARGS --listen-addr ${P2P_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/9000}"
+ARGS=(--data-dir "${DATA_DIR:-/data}" --listen-addr "${P2P_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/9000}")

 if [ -n "$VALIDATOR_SECRET_KEY" ]; then
-    ARGS="$ARGS --secret-key $VALIDATOR_SECRET_KEY"
+    ARGS+=(--secret-key "$VALIDATOR_SECRET_KEY")
 fi

 if [ -n "$NETUID" ]; then
-    ARGS="$ARGS --netuid $NETUID"
+    ARGS+=(--netuid "$NETUID")
 fi

 if [ -n "$BOOTSTRAP_PEERS" ]; then
     # Split by comma and add each peer
     IFS=',' read -ra PEERS <<< "$BOOTSTRAP_PEERS"
     for peer in "${PEERS[@]}"; do
-        ARGS="$ARGS --bootstrap $peer"
+        ARGS+=(--bootstrap "$peer")
     done
 fi

 if [ "$NO_BITTENSOR" = "true" ]; then
-    ARGS="$ARGS --no-bittensor"
+    ARGS+=(--no-bittensor)
 fi

 echo "Starting validator-node with args: $ARGS"
-exec validator-node $ARGS
+exec validator-node "${ARGS[@]}" "$@"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Build command arguments
ARGS="--data-dir ${DATA_DIR:-/data}"
ARGS="$ARGS --listen-addr ${P2P_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/9000}"
if [ -n "$VALIDATOR_SECRET_KEY" ]; then
ARGS="$ARGS --secret-key $VALIDATOR_SECRET_KEY"
fi
if [ -n "$NETUID" ]; then
ARGS="$ARGS --netuid $NETUID"
fi
if [ -n "$BOOTSTRAP_PEERS" ]; then
# Split by comma and add each peer
IFS=',' read -ra PEERS <<< "$BOOTSTRAP_PEERS"
for peer in "${PEERS[@]}"; do
ARGS="$ARGS --bootstrap $peer"
done
fi
if [ "$NO_BITTENSOR" = "true" ]; then
ARGS="$ARGS --no-bittensor"
fi
echo "Starting validator-node with args: $ARGS"
exec validator-node $ARGS
# Build command arguments
ARGS=(--data-dir "${DATA_DIR:-/data}" --listen-addr "${P2P_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/9000}")
if [ -n "$VALIDATOR_SECRET_KEY" ]; then
ARGS+=(--secret-key "$VALIDATOR_SECRET_KEY")
fi
if [ -n "$NETUID" ]; then
ARGS+=(--netuid "$NETUID")
fi
if [ -n "$BOOTSTRAP_PEERS" ]; then
# Split by comma and add each peer
IFS=',' read -ra PEERS <<< "$BOOTSTRAP_PEERS"
for peer in "${PEERS[@]}"; do
ARGS+=(--bootstrap "$peer")
done
fi
if [ "$NO_BITTENSOR" = "true" ]; then
ARGS+=(--no-bittensor)
fi
echo "Starting validator-node with args: $ARGS"
exec validator-node "${ARGS[@]}" "$@"
🤖 Prompt for AI Agents
In `@tests/docker/entrypoint-test.sh` around lines 10 - 35, The script builds
command args into a single string variable ARGS and then calls exec
validator-node $ARGS which causes word-splitting, glob expansion and drops any
extra script args; change to use a bash array (e.g., args_array) and append
elements (like "--data-dir", "${DATA_DIR:-/data}", "--listen-addr",
"${P2P_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/9000}", conditional pushes for SECRET_KEY,
NETUID, each bootstrap peer, and "--no-bittensor") and finally append "$@"
before calling exec validator-node "${args_array[@]}" so arguments are preserved
and not split by the shell.

@echobt echobt merged commit 6b67228 into main Feb 5, 2026
7 checks passed
@echobt echobt deleted the test/multi-validator-docker-tests branch February 5, 2026 00:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant