Skip to content

API Reference

Complete reference for HTTPTests GitHub Action inputs, outputs, and generated configurations.

GitHub Action Inputs

httptests-directory

Type: string (required)

Description: Path to the directory containing the .httptests folder.

Examples:

yaml
- uses: serviceguards-com/httptests-action@v2
  with:
    httptests-directory: .

- uses: serviceguards-com/httptests-action@v2
  with:
    httptests-directory: ./my-service

- uses: serviceguards-com/httptests-action@v2
  with:
    httptests-directory: ./services/api-gateway

Notes:

  • Path is relative to repository root
  • Must contain a .httptests subdirectory
  • Must have a Dockerfile in this directory

python-version

Type: string (optional)

Default: 3.x

Description: Python version to use for test execution.

Examples:

yaml
- uses: serviceguards-com/httptests-action@v2
  with:
    httptests-directory: ./my-service
    python-version: '3.11'

- uses: serviceguards-com/httptests-action@v2
  with:
    httptests-directory: ./my-service
    python-version: '3.x'  # Latest 3.x

Supported Versions:

  • 3.x - Latest Python 3
  • 3.11 - Python 3.11
  • 3.10 - Python 3.10
  • 3.9 - Python 3.9

Exit Codes

HTTPTests uses standard exit codes:

CodeMeaningDescription
0SuccessAll tests passed
1FailureOne or more tests failed
2ErrorConfiguration or setup error

Examples:

yaml
# Exit code 0 - Success
✅ All tests passed

# Exit code 1 - Test failure
❌ Test failed: Status code 500 (expected 200)

# Exit code 2 - Configuration error
❌ ERROR: .httptests directory not found

Generated Docker Compose

HTTPTests automatically generates a docker-compose.yml file in .httptests/ directory.

Basic Structure

yaml
version: "3.9"

services:
  mock:
    container_name: httptests_mock
    image: mendhak/http-https-echo:18
    environment:
      - HTTP_PORT=80
      - HTTPS_PORT=443
    networks:
      default:
        aliases:
          - backend

  nginx:
    container_name: httptests_nginx
    build:
      context: ..
      dockerfile: Dockerfile
    ports:
      - "80:80"
    networks:
      - default
    depends_on:
      - mock

With Additional Ports

Input config.yml:

yaml
mock:
  additional_ports:
    - 5001
    - 8080
  network_aliases:
    - backend

Generated docker-compose.yml:

yaml
version: "3.9"

services:
  mock:
    container_name: httptests_mock
    image: mendhak/http-https-echo:18
    environment:
      - HTTP_PORT=80
      - HTTPS_PORT=443
    networks:
      default:
        aliases:
          - backend

  mock-forwarder-5001:
    container_name: httptests_forwarder_5001
    image: alpine/socat:latest
    command: "TCP-LISTEN:5001,fork,reuseaddr TCP:mock:80"
    networks:
      default:
        aliases:
          - backend
    depends_on:
      - mock

  mock-forwarder-8080:
    container_name: httptests_forwarder_8080
    image: alpine/socat:latest
    command: "TCP-LISTEN:8080,fork,reuseaddr TCP:mock:80"
    networks:
      default:
        aliases:
          - backend
    depends_on:
      - mock

  nginx:
    container_name: httptests_nginx
    build:
      context: ..
      dockerfile: Dockerfile
    ports:
      - "80:80"
    networks:
      - default
    depends_on:
      - mock
      - mock-forwarder-5001
      - mock-forwarder-8080

With Environment Variables

Input config.yml:

yaml
nginx:
  environment:
    API_VERSION: v1
    DEBUG: "true"

Generated docker-compose.yml:

yaml
nginx:
  # ...
  environment:
    - API_VERSION=v1
    - DEBUG=true

Container Names

HTTPTests uses consistent container naming:

ContainerName PatternExample
Mock Servicehttptests_mockhttptests_mock
Port Forwarderhttptests_forwarder_{port}httptests_forwarder_5001
Nginx Servicehttptests_nginxhttptests_nginx

Project Name: Based on directory name

  • Input: ./api-gateway
  • Project: httptests-api-gateway

Network Configuration

All services are on the same Docker network:

yaml
networks:
  default:

Network Aliases:

Mock service is accessible via configured aliases:

yaml
mock:
  network_aliases:
    - backend
    - api-service

Results in:

yaml
networks:
  default:
    aliases:
      - backend
      - api-service

Environment Variables

Mock Service Environment

Always set:

  • HTTP_PORT=80
  • HTTPS_PORT=443

Configurable:

yaml
mock:
  http_port: 8080    # Changes HTTP_PORT
  https_port: 8443   # Changes HTTPS_PORT

Nginx Service Environment

From config.yml:

yaml
nginx:
  environment:
    VAR_NAME: value

Becomes:

yaml
nginx:
  environment:
    - VAR_NAME=value

Test Output Format

Success Output

🔧 Adding X-Upstream-Target headers to nginx configs...
🚀 Starting environment...
🧪 Running tests for httptests-{project}

test_endpoints (__main__.IntegrationTests.test_endpoints) ... ok
  → Testing: GET api.example.com/health
    ✓ Status code: 200 (expected 200)
    ✓ Response header: content-type = application/json
============================================================
Total assertions passed: 2
============================================================

Failure Output

🔧 Adding X-Upstream-Target headers to nginx configs...
🚀 Starting environment...
🧪 Running tests for httptests-{project}

test_endpoints (__main__.IntegrationTests.test_endpoints) ... FAIL
  → Testing: GET api.example.com/health
    ✗ Status code: 500 (expected 200)
    ✓ Response header: content-type = application/json
============================================================
Total assertions passed: 1
Total assertions failed: 1
============================================================

=== Nginx Logs ===
2025/10/30 12:00:00 [error] nginx error message

HTTP Mock Service

HTTPTests uses mendhak/http-https-echo.

Features

  • Echoes back all request details
  • Returns JSON response with:
    • Request method
    • Request path
    • Request headers
    • Request body
    • Query parameters

Example Response

json
{
  "path": "/api/users",
  "headers": {
    "host": "backend",
    "x-forwarded-for": "172.18.0.3",
    "x-real-ip": "172.18.0.3",
    "x-request-id": "abc123"
  },
  "method": "GET",
  "body": "",
  "fresh": false,
  "hostname": "backend",
  "ip": "::ffff:172.18.0.3",
  "ips": [],
  "protocol": "http",
  "query": {},
  "xhr": false
}

Automatic Header Injection

HTTPTests runs add_upstream_headers.py before tests:

What It Does

  1. Scans all .conf files
  2. Finds proxy_pass directives
  3. Extracts upstream URL
  4. Adds proxy_set_header X-Upstream-Target "{upstream}";

Example

Input:

nginx
location /api/ {
    proxy_pass http://backend:5001/;
}

Output:

nginx
location /api/ {
    proxy_pass http://backend:5001/;
    proxy_set_header X-Upstream-Target "backend:5001";
}

Supported Patterns

nginx
# Basic
proxy_pass http://backend:80/;
# → "backend:80"

# With path
proxy_pass http://backend:80/api/;
# → "backend:80"

# Upstream block
proxy_pass http://backend_cluster;
# → "backend_cluster"

# Variables
proxy_pass http://$upstream_host:$port/;
# → "$upstream_host:$port"

File Locations

your-service/
├── Dockerfile                          # Service container
├── nginx.conf                          # Nginx config
└── .httptests/
    ├── config.yml                      # HTTPTests config
    ├── test.json                       # Test definitions
    └── docker-compose.yml             # Generated (don't commit)

Note: docker-compose.yml is generated automatically. Add to .gitignore:

gitignore
.httptests/docker-compose.yml

Resource Requirements

Minimum Requirements

  • Docker: Version 20.10+
  • Docker Compose: V2 (docker compose, not docker-compose)
  • Python: 3.9+
  • Memory: 512MB per test suite
  • Disk: 100MB per test suite
  • Memory: 1GB per test suite
  • CPU: 2+ cores for parallel testing
  • Disk: 500MB for Docker images

Timeouts

Service Startup

  • Default wait: 60 seconds
  • Retry interval: 2 seconds
  • Max attempts: 30

HTTP Requests

  • Connect timeout: 10 seconds
  • Read timeout: 30 seconds

GitHub Actions

yaml
jobs:
  test:
    timeout-minutes: 10  # Recommended

Limitations

Current Limitations

  • Only tests HTTP/HTTPS (no WebSocket, gRPC)
  • Single nginx container per test
  • Mock service only (no real backends)
  • No persistent storage testing
  • No multi-step/stateful tests

Workarounds

Multiple containers:

yaml
# Use network aliases to simulate multiple services
mock:
  network_aliases:
    - service-1
    - service-2
    - service-3

Different ports:

yaml
# Use additional_ports
mock:
  additional_ports:
    - 5001
    - 5002

Released under the MIT License.