5.9 KiB
5.9 KiB
Directory Structure
This document explains the directory structure of the project, particularly the distinction between test/ vs tests/ and script/ vs scripts/.
Directory Overview
Foundry Directories (Solidity)
test/ - Foundry Test Files
- Purpose: Contains Foundry test files (Solidity)
- File Pattern:
*.t.sol - Usage:
forge test - Contents:
Aggregator.t.sol- Oracle aggregator testsMulticall.t.sol- Multicall utility testsWETH.t.sol- WETH token tests
script/ - Foundry Deployment Scripts
- Purpose: Contains Foundry deployment scripts (Solidity)
- File Pattern:
*.s.sol - Usage:
forge script script/Deploy.s.sol --rpc-url $RPC_URL --broadcast - Contents:
Deploy.s.sol- Main deployment scriptDeployWETH.s.sol- WETH deployment scriptDeployMulticall.s.sol- Multicall deployment scriptDeployOracle.s.sol- Oracle deployment script
Shell Script Directories
tests/ - Shell Script Tests
- Purpose: Contains shell script tests for infrastructure and network
- File Pattern:
*.sh - Usage:
./tests/health-check.sh,./tests/load-test.sh - Contents:
health-check.sh- Network health check scriptload-test.sh- RPC endpoint load test script
scripts/ - Shell Scripts
- Purpose: Contains utility shell scripts for deployment, key management, etc.
- File Pattern:
*.sh - Usage:
./scripts/generate-genesis-proper.sh 4 - Contents:
generate-genesis-proper.sh- Canonical QBFT genesis file generation scriptgenerate-genesis.sh- Compatibility wrapper for the canonical generatordeployment/- Deployment scriptsdeploy-weth.sh- WETH deployment scriptdeploy-multicall.sh- Multicall deployment script
key-management/- Key management scriptsgenerate-validator-keys.sh- Validator key generationgenerate-oracle-keys.sh- Oracle key generationazure-keyvault-setup.sh- Azure Key Vault setup
Why Two Sets of Directories?
Foundry Convention
- Foundry (the Solidity testing framework) uses singular directory names:
test/for test filesscript/for deployment scripts
- These are Foundry's default directories and should not be renamed
Shell Scripts Convention
- Shell scripts use plural directory names to distinguish from Foundry:
tests/for shell script testsscripts/for shell script utilities
- This avoids confusion and follows common project conventions
Usage Examples
Running Foundry Tests
# Run all Foundry tests
forge test
# Run specific test
forge test --match-test testDeposit
# Run with verbosity
forge test -vvv
Running Foundry Scripts
# Deploy all contracts
forge script script/Deploy.s.sol --rpc-url $RPC_URL --broadcast
# Deploy WETH
forge script script/DeployWETH.s.sol --rpc-url $RPC_URL --broadcast
# Deploy with private key
forge script script/DeployOracle.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY
Running Shell Script Tests
# Health check
./tests/health-check.sh
# Load test
./tests/load-test.sh
# With custom RPC URL
RPC_URL=https://rpc.d-bis.org ./tests/health-check.sh
Running Shell Scripts
# Generate genesis
./scripts/generate-genesis-proper.sh 4
# Generate validator keys
./scripts/key-management/generate-validator-keys.sh 4
# Deploy WETH (shell script wrapper)
./scripts/deployment/deploy-weth.sh
Makefile Targets
The Makefile provides convenient targets for common operations:
# Run all tests (Foundry + shell scripts)
make test
# Run only Foundry tests
make contracts
# Generate genesis
make genesis
# Generate keys
make keys
Configuration
Foundry Configuration (foundry.toml)
src = "contracts"- Source directory for contractstest/- Default test directory (not specified, uses default)script/- Default script directory (not specified, uses default)- For monorepo day-to-day work, prefer the scoped workflow in FOUNDRY_MONOREPO_SCOPES.md so Forge only compiles the contract subtree you are editing.
Test Configuration
- Foundry tests: Configured in
foundry.toml - Shell script tests: No special configuration needed
Best Practices
- Foundry Tests: Place all Solidity test files in
test/ - Foundry Scripts: Place all deployment scripts in
script/ - Shell Tests: Place infrastructure/network tests in
tests/ - Shell Scripts: Place utility scripts in
scripts/ - Naming: Use descriptive names that indicate purpose
- Documentation: Document complex scripts in their headers
Adding New Files
Adding a Foundry Test
- Create file in
test/directory - Name it
*.t.sol(e.g.,MyContract.t.sol) - Import from
contracts/directory - Run with
forge test
Adding a Foundry Script
- Create file in
script/directory - Name it
*.s.sol(e.g.,DeployMyContract.s.sol) - Import from
contracts/directory - Run with
forge script script/DeployMyContract.s.sol --rpc-url $RPC_URL --broadcast
Adding a Shell Test
- Create file in
tests/directory - Name it
*.sh(e.g.,my-test.sh) - Make it executable:
chmod +x tests/my-test.sh - Run with
./tests/my-test.sh
Adding a Shell Script
- Create file in
scripts/directory (or appropriate subdirectory) - Name it
*.sh(e.g.,my-script.sh) - Make it executable:
chmod +x scripts/my-script.sh - Run with
./scripts/my-script.sh
Summary
| Directory | Type | Purpose | Files |
|---|---|---|---|
test/ |
Foundry | Solidity test files | *.t.sol |
script/ |
Foundry | Solidity deployment scripts | *.s.sol |
tests/ |
Shell | Infrastructure/network tests | *.sh |
scripts/ |
Shell | Utility scripts | *.sh |
This structure follows Foundry conventions while providing clear separation between Solidity and shell script files.