Files
attune/work-summary/sessions/2026-01-28-tier1-tests-preparation.md
2026-02-04 17:46:30 -06:00

8.8 KiB

Work Summary: Tier 1 E2E Tests Preparation

Date: 2026-01-28
Focus: Fixing E2E test infrastructure issues to enable tier1 test execution


Overview

Prepared the tier1 E2E test suite for execution by fixing a critical Python error in the test helper client. The AttuneClient class had duplicate method definitions that needed to be resolved before tests could run properly.


Changes Made

1. Fixed Duplicate create_sensor Method

Problem: The AttuneClient class in tests/helpers/client.py had two methods named create_sensor with completely different signatures:

  1. First method (lines 601-636): API-based approach

    • Signature: create_sensor(pack_ref, name, trigger_types, entrypoint, poll_interval, **kwargs)
    • Implementation: POST request to /api/v1/sensors
    • Status: Not used by any code
  2. Second method (lines 638-759): SQL-based approach

    • Signature: create_sensor(ref, trigger_id, trigger_ref, label, description, entrypoint, runtime_ref, pack_ref, enabled, config, **kwargs)
    • Implementation: Direct SQL INSERT via psycopg2
    • Status: Used by all timer fixture helpers

Python Behavior: When you define two methods with the same name in a class, Python uses the second definition and the first becomes unreachable dead code. This works but is confusing and indicates a design problem.

Root Cause: The first method was likely created when planning to use the API endpoint, but the API endpoint for sensor creation may not have been fully implemented at that time. The second method was added later to work around this by directly inserting into the database, and the first method was never removed.

Solution: Removed the first (unused) API-based create_sensor method definition (lines 601-636).

Code Removed:

def create_sensor(
    self,
    pack_ref: str,
    name: str,
    trigger_types: List[str],
    entrypoint: str,
    poll_interval: int = 30,
    **kwargs,
) -> Dict[str, Any]:
    """
    Create sensor

    Args:
        pack_ref: Pack reference
        name: Sensor name
        trigger_types: List of trigger types this sensor monitors
        entrypoint: Sensor entry point
        poll_interval: Polling interval in seconds
        **kwargs: Additional sensor fields

    Returns:
        Created sensor data
    """
    payload = {
        "pack_ref": pack_ref,
        "name": name,
        "trigger_types": trigger_types,
        "entrypoint": entrypoint,
        "poll_interval": poll_interval,
        **kwargs,
    }
    response = self.post("/api/v1/sensors", json=payload)
    return response["data"]

What Remains: The SQL-based create_sensor method which matches the signature used by fixture helpers:

  • create_interval_timer() in tests/helpers/fixtures.py
  • create_date_timer() in tests/helpers/fixtures.py
  • create_cron_timer() in tests/helpers/fixtures.py

Test Infrastructure Status

Tier 1 E2E Tests

Test Collection: All 34 tests collect successfully

Test Breakdown:

  • test_t1_01_interval_timer.py - 2 tests (interval timer automation)
  • test_t1_02_date_timer.py - 3 tests (one-shot date timer)
  • test_t1_03_cron_timer.py - 4 tests (cron-based timer)
  • test_t1_04_webhook_trigger.py - 4 tests (webhook triggers)
  • test_t1_05_workflow_with_items.py - 5 tests (with_items concept)
  • test_t1_06_datastore.py - 7 tests (datastore operations)
  • test_t1_07_multi_tenant.py - 4 tests (tenant isolation)
  • test_t1_08_action_failure.py - 5 tests (failure handling)

Total: 34 tier1 tests ready to run

Test Dependencies

Services Required:

  • API service (attune-api)
  • Executor service (attune-executor)
  • Worker service (attune-worker)
  • Sensor service (attune-sensor)
  • Notifier service (attune-notifier)

Database Required:

  • PostgreSQL with attune_e2e database
  • All migrations applied
  • Core pack loaded with timers and actions

Python Environment:

  • Virtual environment at tests/venvs/e2e
  • All requirements installed from tests/requirements.txt
  • No module import errors

Validation Performed

Python Syntax Check

python3 -m py_compile tests/helpers/client.py
# ✅ No syntax errors

python3 -m py_compile tests/helpers/fixtures.py
# ✅ No syntax errors

Test Collection

cd tests && source venvs/e2e/bin/activate
python3 -m pytest e2e/tier1/ --collect-only -q
# ✅ collected 34 items in 0.05s

Files Modified

  1. tests/helpers/client.py - Removed duplicate create_sensor method (lines 601-636)
  2. work-summary/PROBLEM.md - Documented the fix in "Recently Fixed Issues" section

Next Steps

Immediate (Before Running Tests)

  1. Set up E2E database

    ./scripts/setup-e2e-db.sh
    
  2. Start all 5 services

    ./scripts/start-e2e-services.sh
    
  3. Verify services are running

    curl http://localhost:8080/health
    # Should return: {"status":"ok"}
    

Test Execution

  1. Run tier1 tests (verbose)

    cd tests
    ./run_e2e_tests.sh --tier 1 -v
    
  2. Identify failing tests

    • Document which tests fail and why
    • Categorize failures by type (sensor issues, API issues, timing issues, etc.)
  3. Fix failures systematically

    • Start with simplest failures (likely configuration or setup issues)
    • Move to integration issues (sensor service, message queue)
    • Finally address timing/concurrency issues

Expected Issues

Based on previous work summaries, potential issues to watch for:

  1. Sensor Service Integration

    • Timer sensors may not fire events if sensor service isn't properly loading sensors
    • restart_sensor_service() function may need refinement
    • Database sensor records may not be automatically loaded by sensor service
  2. Timer Precision

    • Interval timers may have jitter beyond ±1 second tolerance
    • Cron timers may have timezone issues
    • Date timers firing in past may need special handling
  3. Event Flow

    • Events may not create enforcements if rule evaluation fails
    • Enforcements may not create executions if executor has issues
    • Executions may not complete if worker has runtime issues
  4. Database State

    • Test isolation may be incomplete (tests affect each other)
    • Cleanup between tests may be needed
    • Race conditions in concurrent test execution

Testing Infrastructure Notes

How Timers Work in Tests

  1. Fixture creates timer sensor:

    trigger = create_interval_timer(client, interval_seconds=5, pack_ref="test.pack")
    
  2. This creates:

    • Gets/creates core.intervaltimer trigger
    • Creates sensor record in database with timer config
    • Calls restart_sensor_service() to reload sensors
  3. Sensor service:

    • Loads sensors from database on startup
    • Timer sensors fire events at specified intervals
    • Events are inserted into database and published to message queue
  4. Executor service:

    • Listens for events
    • Evaluates rules matching the trigger
    • Creates enforcements for matching rules
    • Creates executions for enforcements
    • Publishes execution requests to worker queue
  5. Worker service:

    • Receives execution requests
    • Executes actions (python, shell, etc.)
    • Reports results back to executor
  6. Tests wait for:

    • Events to be created (via wait_for_event_count())
    • Executions to be created (via wait_for_execution_count())
    • Executions to complete (via wait_for_execution_status())

Key Helper Functions

Timer Creation:

  • create_interval_timer(client, interval_seconds, pack_ref) - Fires every N seconds
  • create_date_timer(client, fire_at, pack_ref) - Fires once at specific time
  • create_cron_timer(client, cron_expression, pack_ref) - Fires on cron schedule

Action Creation:

  • create_echo_action(client, pack_ref) - Simple action that echoes input
  • create_failing_action(client, pack_ref, exit_code) - Action that always fails
  • create_sleep_action(client, pack_ref, duration) - Action that sleeps

Rule Creation:

  • create_rule(client, trigger_id, action_ref, pack_ref) - Links trigger to action

Wait Functions:

  • wait_for_event_count(client, count, trigger_id, timeout) - Wait for N events
  • wait_for_execution_count(client, count, action_ref, timeout) - Wait for N executions
  • wait_for_execution_status(client, execution_id, status, timeout) - Wait for specific status

Conclusion

Fixed critical Python error in E2E test client by removing duplicate method definition. All 34 tier1 tests now collect successfully and are ready to run once services are started.

Current Status: Infrastructure Ready - Test execution can proceed

Time Spent: ~30 minutes

Next Session: Start services and run tier1 tests to identify actual failures