Add comprehensive E2E tests for materia CLI
- Add pytest and pytest-cov for testing - Add niquests for modern HTTP/2 support (keep requests for hcloud compatibility) - Create 13 E2E tests covering CLI, workers, pipelines, and secrets (71% coverage) - Fix Pulumi ESC environment path (beanflows/prod) and secret key names - Update GitLab CI to run CLI tests with coverage reporting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -12,9 +12,9 @@ from materia.secrets import get_secret
|
||||
|
||||
|
||||
def _get_client() -> Client:
|
||||
token = get_secret("HETZNER_TOKEN")
|
||||
token = get_secret("HETZNER_API_TOKEN")
|
||||
if not token:
|
||||
raise ValueError("HETZNER_TOKEN not found in secrets")
|
||||
raise ValueError("HETZNER_API_TOKEN not found in secrets")
|
||||
return Client(token=token)
|
||||
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ def _load_environment() -> dict[str, str]:
|
||||
"""Load secrets from Pulumi ESC environment."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["esc", "env", "open", "prod", "--format", "json"],
|
||||
["esc", "env", "open", "beanflows/prod", "--format", "json"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
data = json.loads(result.stdout)
|
||||
return data.get("values", {})
|
||||
return data.get("environmentVariables", {})
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise RuntimeError(f"Failed to load ESC environment: {e.stderr}")
|
||||
except FileNotFoundError:
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
# Pipeline Configuration
|
||||
# Defines SQLMesh pipelines, schedules, and worker requirements
|
||||
|
||||
pipelines:
|
||||
# Daily extraction of USDA PSD data
|
||||
- name: extract_psd
|
||||
type: extraction
|
||||
schedule: "0 2 * * *" # 2 AM UTC daily
|
||||
command: "extract_psd"
|
||||
worker:
|
||||
instance_type: scheduler # Runs on lightweight scheduler instance
|
||||
timeout_minutes: 30
|
||||
on_success:
|
||||
- trigger: transform_psd_staging
|
||||
|
||||
# Transform raw PSD data to staging layer
|
||||
- name: transform_psd_staging
|
||||
type: transformation
|
||||
schedule: "0 3 * * *" # 3 AM UTC daily (or triggered after extraction)
|
||||
command: "cd transform/sqlmesh_materia && sqlmesh plan --select-model tag:staging"
|
||||
worker:
|
||||
instance_type: worker # Needs more resources for DuckDB
|
||||
min_memory_gb: 8
|
||||
timeout_minutes: 60
|
||||
on_success:
|
||||
- trigger: transform_psd_cleaned
|
||||
|
||||
# Transform staging to cleaned layer
|
||||
- name: transform_psd_cleaned
|
||||
type: transformation
|
||||
schedule: "0 4 * * *" # 4 AM UTC daily
|
||||
command: "cd transform/sqlmesh_materia && sqlmesh plan --select-model tag:cleaned"
|
||||
worker:
|
||||
instance_type: worker
|
||||
min_memory_gb: 16 # Larger transformations
|
||||
timeout_minutes: 120
|
||||
on_success:
|
||||
- trigger: transform_psd_serving
|
||||
|
||||
# Transform cleaned to serving layer
|
||||
- name: transform_psd_serving
|
||||
type: transformation
|
||||
schedule: "0 5 * * *" # 5 AM UTC daily
|
||||
command: "cd transform/sqlmesh_materia && sqlmesh plan --select-model tag:serving"
|
||||
worker:
|
||||
instance_type: worker
|
||||
min_memory_gb: 8
|
||||
timeout_minutes: 60
|
||||
on_success:
|
||||
- notify: slack # TODO: Add Slack webhook
|
||||
|
||||
# Full refresh pipeline (weekly)
|
||||
- name: full_refresh
|
||||
type: maintenance
|
||||
schedule: "0 1 * * 0" # 1 AM UTC every Sunday
|
||||
command: "cd transform/sqlmesh_materia && sqlmesh plan --no-auto-apply --select-model * --full-refresh"
|
||||
worker:
|
||||
instance_type: worker
|
||||
min_memory_gb: 32 # Needs big instance for full refresh
|
||||
timeout_minutes: 360 # 6 hours max
|
||||
enabled: false # Disabled by default, enable manually when needed
|
||||
|
||||
# Worker instance mapping
|
||||
# Maps instance types to actual Hetzner server IPs/names
|
||||
workers:
|
||||
scheduler:
|
||||
type: persistent
|
||||
server: materia-scheduler # Always running
|
||||
max_concurrent_jobs: 3
|
||||
|
||||
worker:
|
||||
type: on_demand
|
||||
servers:
|
||||
- name: materia-worker-01
|
||||
instance_type: ccx22 # 4 vCPU, 16GB RAM
|
||||
memory_gb: 16
|
||||
max_concurrent_jobs: 2
|
||||
# Add more workers as needed:
|
||||
# - name: materia-worker-02
|
||||
# instance_type: ccx32 # 8 vCPU, 32GB RAM
|
||||
# memory_gb: 32
|
||||
# max_concurrent_jobs: 4
|
||||
|
||||
# Notification channels
|
||||
notifications:
|
||||
slack:
|
||||
enabled: false
|
||||
webhook_url_secret: SLACK_WEBHOOK_URL
|
||||
notify_on:
|
||||
- failure
|
||||
- success_after_failure
|
||||
|
||||
email:
|
||||
enabled: false
|
||||
recipients:
|
||||
- hendrik.note@gmail.com
|
||||
notify_on:
|
||||
- failure
|
||||
Reference in New Issue
Block a user