Files
attune/docker/distributable/packs/core/TESTING.md
David Culbreth 938c271ff5
Some checks failed
CI / Rustfmt (push) Successful in 22s
CI / Cargo Audit & Deny (push) Successful in 36s
CI / Security Blocking Checks (push) Successful in 6s
CI / Web Blocking Checks (push) Successful in 53s
CI / Web Advisory Checks (push) Successful in 34s
Publish Images / Resolve Publish Metadata (push) Successful in 1s
CI / Security Advisory Checks (push) Successful in 38s
CI / Clippy (push) Successful in 2m7s
Publish Images / Publish Docker Dist Bundle (push) Failing after 19s
Publish Images / Publish web (amd64) (push) Successful in 49s
Publish Images / Publish web (arm64) (push) Successful in 3m31s
CI / Tests (push) Successful in 8m48s
Publish Images / Build Rust Bundles (amd64) (push) Successful in 12m42s
Publish Images / Build Rust Bundles (arm64) (push) Successful in 12m19s
Publish Images / Publish agent (amd64) (push) Successful in 26s
Publish Images / Publish api (amd64) (push) Successful in 38s
Publish Images / Publish notifier (amd64) (push) Successful in 42s
Publish Images / Publish executor (amd64) (push) Successful in 46s
Publish Images / Publish agent (arm64) (push) Successful in 56s
Publish Images / Publish api (arm64) (push) Successful in 1m52s
Publish Images / Publish executor (arm64) (push) Successful in 2m2s
Publish Images / Publish notifier (arm64) (push) Successful in 2m3s
Publish Images / Publish manifest attune/agent (push) Successful in 6s
Publish Images / Publish manifest attune/api (push) Successful in 11s
Publish Images / Publish manifest attune/executor (push) Successful in 10s
Publish Images / Publish manifest attune/notifier (push) Successful in 8s
Publish Images / Publish manifest attune/web (push) Successful in 8s
distributable, please
2026-03-26 12:26:23 -05:00

8.1 KiB

Core Pack Testing Guide

Quick reference for testing core pack actions and sensors locally.


Prerequisites

# Ensure scripts are executable
chmod +x packs/core/actions/*.sh
chmod +x packs/core/actions/*.py
chmod +x packs/core/sensors/*.py

# Install Python dependencies
pip install requests>=2.28.0

Testing Actions

Actions receive parameters via environment variables prefixed with ATTUNE_ACTION_.

Test core.echo

# Basic echo
export ATTUNE_ACTION_MESSAGE="Hello, Attune!"
./packs/core/actions/echo.sh

# With uppercase conversion
export ATTUNE_ACTION_MESSAGE="test message"
export ATTUNE_ACTION_UPPERCASE=true
./packs/core/actions/echo.sh

Expected Output:

Hello, Attune!
TEST MESSAGE

Test core.sleep

# Sleep for 2 seconds
export ATTUNE_ACTION_SECONDS=2
export ATTUNE_ACTION_MESSAGE="Sleeping..."
time ./packs/core/actions/sleep.sh

Expected Output:

Sleeping...
Slept for 2 seconds

real    0m2.004s

Test core.noop

# No operation with message
export ATTUNE_ACTION_MESSAGE="Testing noop"
./packs/core/actions/noop.sh

# With custom exit code
export ATTUNE_ACTION_EXIT_CODE=0
./packs/core/actions/noop.sh
echo "Exit code: $?"

Expected Output:

[NOOP] Testing noop
No operation completed successfully
Exit code: 0

Test core.http_request

# Simple GET request
export ATTUNE_ACTION_URL="https://httpbin.org/get"
export ATTUNE_ACTION_METHOD="GET"
python3 ./packs/core/actions/http_request.py

# POST with JSON body
export ATTUNE_ACTION_URL="https://httpbin.org/post"
export ATTUNE_ACTION_METHOD="POST"
export ATTUNE_ACTION_JSON_BODY='{"name": "test", "value": 123}'
python3 ./packs/core/actions/http_request.py

# With custom headers
export ATTUNE_ACTION_URL="https://httpbin.org/headers"
export ATTUNE_ACTION_METHOD="GET"
export ATTUNE_ACTION_HEADERS='{"X-Custom-Header": "test-value"}'
python3 ./packs/core/actions/http_request.py

# With query parameters
export ATTUNE_ACTION_URL="https://httpbin.org/get"
export ATTUNE_ACTION_METHOD="GET"
export ATTUNE_ACTION_QUERY_PARAMS='{"foo": "bar", "page": "1"}'
python3 ./packs/core/actions/http_request.py

# With timeout
export ATTUNE_ACTION_URL="https://httpbin.org/delay/5"
export ATTUNE_ACTION_METHOD="GET"
export ATTUNE_ACTION_TIMEOUT=2
python3 ./packs/core/actions/http_request.py

Expected Output:

{
  "status_code": 200,
  "headers": {
    "Content-Type": "application/json",
    ...
  },
  "body": "...",
  "json": {
    "args": {},
    "headers": {...},
    ...
  },
  "elapsed_ms": 234,
  "url": "https://httpbin.org/get",
  "success": true
}

Testing Sensors

Sensors receive configuration via environment variables prefixed with ATTUNE_SENSOR_.

Test core.interval_timer_sensor

# Create test trigger instances JSON
export ATTUNE_SENSOR_TRIGGERS='[
  {
    "id": 1,
    "ref": "core.intervaltimer",
    "config": {
      "unit": "seconds",
      "interval": 5
    }
  }
]'

# Run sensor (will output events every 5 seconds)
python3 ./packs/core/sensors/interval_timer_sensor.py

Expected Output:

Interval Timer Sensor started (check_interval=1s)
{"type": "interval", "interval_seconds": 5, "fired_at": "2024-01-20T12:00:00Z", "execution_count": 1, "sensor_ref": "core.interval_timer_sensor", "trigger_instance_id": 1, "trigger_ref": "core.intervaltimer"}
{"type": "interval", "interval_seconds": 5, "fired_at": "2024-01-20T12:00:05Z", "execution_count": 2, "sensor_ref": "core.interval_timer_sensor", "trigger_instance_id": 1, "trigger_ref": "core.intervaltimer"}
...

Press Ctrl+C to stop the sensor.


Testing with Multiple Trigger Instances

# Test multiple timers
export ATTUNE_SENSOR_TRIGGERS='[
  {
    "id": 1,
    "ref": "core.intervaltimer",
    "config": {"unit": "seconds", "interval": 3}
  },
  {
    "id": 2,
    "ref": "core.intervaltimer",
    "config": {"unit": "seconds", "interval": 5}
  },
  {
    "id": 3,
    "ref": "core.intervaltimer",
    "config": {"unit": "seconds", "interval": 10}
  }
]'

python3 ./packs/core/sensors/interval_timer_sensor.py

You should see events firing at different intervals (3s, 5s, 10s).


Validation Tests

Validate YAML Schemas

# Install yamllint (optional)
pip install yamllint

# Validate all YAML files
yamllint packs/core/**/*.yaml

Validate JSON Schemas

# Check parameter schemas are valid JSON Schema
cat packs/core/actions/http_request.yaml | grep -A 50 "parameters:" | python3 -c "
import sys, yaml, json
data = yaml.safe_load(sys.stdin)
print(json.dumps(data, indent=2))
"

Error Testing

Test Invalid Parameters

# Invalid seconds value for sleep
export ATTUNE_ACTION_SECONDS=-1
./packs/core/actions/sleep.sh
# Expected: ERROR: seconds must be between 0 and 3600

# Invalid exit code for noop
export ATTUNE_ACTION_EXIT_CODE=999
./packs/core/actions/noop.sh
# Expected: ERROR: exit_code must be between 0 and 255

# Missing required parameter for HTTP request
unset ATTUNE_ACTION_URL
python3 ./packs/core/actions/http_request.py
# Expected: ERROR: Required parameter 'url' not provided

Performance Testing

Measure Action Execution Time

# Echo action
time for i in {1..100}; do
  export ATTUNE_ACTION_MESSAGE="Test $i"
  ./packs/core/actions/echo.sh > /dev/null
done

# HTTP request action
time for i in {1..10}; do
  export ATTUNE_ACTION_URL="https://httpbin.org/get"
  python3 ./packs/core/actions/http_request.py > /dev/null
done

Integration Testing (with Attune Services)

Prerequisites

# Start Attune services
docker-compose up -d postgres rabbitmq redis

# Run migrations
sqlx migrate run

# Load core pack (future)
# attune pack load packs/core

Test Action Execution via API

# Create execution manually
curl -X POST http://localhost:8080/api/v1/executions \
  -H "Content-Type: application/json" \
  -d '{
    "action_ref": "core.echo",
    "parameters": {
      "message": "API test",
      "uppercase": true
    }
  }'

# Check execution status
curl http://localhost:8080/api/v1/executions/{execution_id}

Test Sensor via Sensor Service

# Start sensor service (future)
# cargo run --bin attune-sensor

# Check events created
curl http://localhost:8080/api/v1/events?limit=10

Troubleshooting

Action Not Executing

# Check file permissions
ls -la packs/core/actions/

# Ensure scripts are executable
chmod +x packs/core/actions/*.sh
chmod +x packs/core/actions/*.py

Python Import Errors

# Install required packages
pip install requests>=2.28.0

# Verify Python version
python3 --version  # Should be 3.8+

Environment Variables Not Working

# Print all ATTUNE_* environment variables
env | grep ATTUNE_

# Test with explicit export
export ATTUNE_ACTION_MESSAGE="test"
echo $ATTUNE_ACTION_MESSAGE

Automated Test Script

Create a test script test_core_pack.sh:

#!/bin/bash
set -e

echo "Testing Core Pack Actions..."

# Test echo
echo "→ Testing core.echo..."
export ATTUNE_ACTION_MESSAGE="Test"
./packs/core/actions/echo.sh > /dev/null
echo "✓ core.echo passed"

# Test sleep
echo "→ Testing core.sleep..."
export ATTUNE_ACTION_SECONDS=1
./packs/core/actions/sleep.sh > /dev/null
echo "✓ core.sleep passed"

# Test noop
echo "→ Testing core.noop..."
export ATTUNE_ACTION_MESSAGE="test"
./packs/core/actions/noop.sh > /dev/null
echo "✓ core.noop passed"

# Test HTTP request
echo "→ Testing core.http_request..."
export ATTUNE_ACTION_URL="https://httpbin.org/get"
export ATTUNE_ACTION_METHOD="GET"
python3 ./packs/core/actions/http_request.py > /dev/null
echo "✓ core.http_request passed"

echo ""
echo "All tests passed! ✓"

Run with:

chmod +x test_core_pack.sh
./test_core_pack.sh

Next Steps

  1. Implement pack loader to register components in database
  2. Update worker service to execute actions from filesystem
  3. Update sensor service to run sensors from filesystem
  4. Add comprehensive integration tests
  5. Create CLI commands for pack management

See docs/core-pack-integration.md for implementation details.