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
240 changes: 240 additions & 0 deletions .github/workflows/test-integration-suite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
name: Integration Tests

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
test-domain-network:
name: Domain & Network Tests
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4

- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '22'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build project
run: npm run build

- name: Build local containers
run: |
echo "=== Building local containers ==="
docker build -t ghcr.io/github/gh-aw-firewall/squid:latest containers/squid/
docker build -t ghcr.io/github/gh-aw-firewall/agent:latest containers/agent/

- name: Pre-test cleanup
run: |
echo "=== Pre-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Run domain & network tests
run: |
echo "=== Running domain & network tests ==="
npm run test:integration -- \
--testPathPatterns="(blocked-domains|dns-servers|empty-domains|wildcard-patterns|ipv6|localhost-access|network-security)" \
--verbose
env:
JEST_TIMEOUT: 180000

- name: Post-test cleanup
if: always()
run: |
echo "=== Post-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Collect logs on failure
if: failure()
run: |
echo "=== Collecting failure logs ==="
docker ps -a || true
docker logs awf-squid 2>&1 || true
docker logs awf-agent 2>&1 || true
ls -la /tmp/awf-* 2>/dev/null || true
sudo cat /tmp/awf-*/squid-logs/access.log 2>/dev/null || true

test-protocol-security:
name: Protocol & Security Tests
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4

- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '22'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build project
run: npm run build

- name: Build local containers
run: |
echo "=== Building local containers ==="
docker build -t ghcr.io/github/gh-aw-firewall/squid:latest containers/squid/
docker build -t ghcr.io/github/gh-aw-firewall/agent:latest containers/agent/

- name: Pre-test cleanup
run: |
echo "=== Pre-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Run protocol & security tests
run: |
echo "=== Running protocol & security tests ==="
npm run test:integration -- \
--testPathPatterns="(protocol-support|credential-hiding|one-shot-tokens|token-unset|git-operations)" \
--verbose
env:
JEST_TIMEOUT: 180000

- name: Post-test cleanup
if: always()
run: |
echo "=== Post-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Collect logs on failure
if: failure()
run: |
echo "=== Collecting failure logs ==="
docker ps -a || true
docker logs awf-squid 2>&1 || true
docker logs awf-agent 2>&1 || true
ls -la /tmp/awf-* 2>/dev/null || true
sudo cat /tmp/awf-*/squid-logs/access.log 2>/dev/null || true

test-container-ops:
name: Container & Ops Tests
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4

- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '22'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build project
run: npm run build

- name: Build local containers
run: |
echo "=== Building local containers ==="
docker build -t ghcr.io/github/gh-aw-firewall/squid:latest containers/squid/
docker build -t ghcr.io/github/gh-aw-firewall/agent:latest containers/agent/

- name: Pre-test cleanup
run: |
echo "=== Pre-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Run container & ops tests
run: |
echo "=== Running container & ops tests ==="
npm run test:integration -- \
--testPathPatterns="(container-workdir|docker-warning|environment-variables|error-handling|exit-code-propagation|log-commands|no-docker|volume-mounts)" \
--verbose
env:
JEST_TIMEOUT: 180000

- name: Post-test cleanup
if: always()
run: |
echo "=== Post-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Collect logs on failure
if: failure()
run: |
echo "=== Collecting failure logs ==="
docker ps -a || true
docker logs awf-squid 2>&1 || true
docker logs awf-agent 2>&1 || true
ls -la /tmp/awf-* 2>/dev/null || true
sudo cat /tmp/awf-*/squid-logs/access.log 2>/dev/null || true

test-api-proxy:
name: API Proxy Tests
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4

- name: Setup Node.js
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version: '22'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build project
run: npm run build

- name: Build local containers
run: |
echo "=== Building local containers ==="
docker build -t ghcr.io/github/gh-aw-firewall/squid:latest containers/squid/
docker build -t ghcr.io/github/gh-aw-firewall/agent:latest containers/agent/

- name: Pre-test cleanup
run: |
echo "=== Pre-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Run API proxy tests
run: |
echo "=== Running API proxy tests ==="
npm run test:integration -- \
--testPathPatterns="api-proxy" \
--verbose
env:
JEST_TIMEOUT: 180000

- name: Post-test cleanup
if: always()
run: |
echo "=== Post-test cleanup ==="
./scripts/ci/cleanup.sh || true

- name: Collect logs on failure
if: failure()
run: |
echo "=== Collecting failure logs ==="
docker ps -a || true
docker logs awf-squid 2>&1 || true
docker logs awf-agent 2>&1 || true
ls -la /tmp/awf-* 2>/dev/null || true
sudo cat /tmp/awf-*/squid-logs/access.log 2>/dev/null || true
32 changes: 30 additions & 2 deletions tests/fixtures/awf-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ export interface AwfOptions {
dnsServers?: string[]; // DNS servers to use (e.g., ['8.8.8.8', '2001:4860:4860::8888'])
allowHostPorts?: string; // Ports or port ranges to allow for host access (e.g., '3000' or '3000-8000')
enableApiProxy?: boolean; // Enable API proxy sidecar for LLM credential management
envAll?: boolean; // Pass all host environment variables to container (--env-all)
cliEnv?: Record<string, string>; // Explicit -e KEY=VALUE flags passed to AWF CLI
rateLimitRpm?: number; // Requests per minute per provider
rateLimitRph?: number; // Requests per hour per provider
rateLimitBytesPm?: number; // Request bytes per minute per provider
noRateLimit?: boolean; // Disable rate limiting
envAll?: boolean; // Pass all host environment variables to container (--env-all)
cliEnv?: Record<string, string>; // Explicit -e KEY=VALUE flags passed to AWF CLI
}

export interface AwfResult {
Expand Down Expand Up @@ -116,6 +116,20 @@ export class AwfRunner {
args.push('--enable-api-proxy');
}

// Add rate limit flags
if (options.rateLimitRpm !== undefined) {
args.push('--rate-limit-rpm', String(options.rateLimitRpm));
}
if (options.rateLimitRph !== undefined) {
args.push('--rate-limit-rph', String(options.rateLimitRph));
}
if (options.rateLimitBytesPm !== undefined) {
args.push('--rate-limit-bytes-pm', String(options.rateLimitBytesPm));
}
if (options.noRateLimit) {
args.push('--no-rate-limit');
}

// Add --env-all flag
if (options.envAll) {
args.push('--env-all');
Expand Down Expand Up @@ -296,6 +310,20 @@ export class AwfRunner {
args.push('--enable-api-proxy');
}

// Add rate limit flags
if (options.rateLimitRpm !== undefined) {
args.push('--rate-limit-rpm', String(options.rateLimitRpm));
}
if (options.rateLimitRph !== undefined) {
args.push('--rate-limit-rph', String(options.rateLimitRph));
}
if (options.rateLimitBytesPm !== undefined) {
args.push('--rate-limit-bytes-pm', String(options.rateLimitBytesPm));
}
if (options.noRateLimit) {
args.push('--no-rate-limit');
}

// Add --env-all flag
if (options.envAll) {
args.push('--env-all');
Expand Down
Loading