Add E2E tests, fix bugs

Made-with: Cursor
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-04-13 05:17:48 +03:00
parent 1f98b5e958
commit 8f7deb3fca
71 changed files with 4740 additions and 29 deletions
@@ -0,0 +1,29 @@
# CI/CD Pipeline
## Woodpecker CI
**Config**: `.woodpecker/build-arm.yml`
**Trigger**: push or manual event on `dev`, `stage`, `main` branches
**Platform label**: `arm64`
## Pipeline Steps
### Step: build-push
**Image**: `docker` (Docker-in-Docker)
**Actions**:
1. Determine tag: `arm` for `main` branch, `{branch}-arm` for others
2. Build Docker image: `docker build -f Dockerfile -t localhost:5000/loader:$TAG .`
3. Push to local registry: `docker push localhost:5000/loader:$TAG`
**Volumes**: Docker socket (`/var/run/docker.sock`)
## Notes
- Only ARM64 builds are configured — no x86/amd64 build target
- Registry is `localhost:5000` — a local Docker registry assumed to be running on the CI runner
- No test step in the pipeline (no tests exist in the codebase)
- No multi-stage build (single Dockerfile, no image size optimization)
@@ -0,0 +1,36 @@
# Containerization
## Dockerfile Summary
**Base image**: `python:3.11-slim`
**Build steps**:
1. Install system deps: `python3-dev`, `gcc`, `pciutils`, `curl`, `gnupg`
2. Install Docker CE CLI (from official Docker apt repo)
3. Install Python deps from `requirements.txt`
4. Copy source code
5. Compile Cython extensions: `python setup.py build_ext --inplace`
**Runtime**: `uvicorn main:app --host 0.0.0.0 --port 8080`
**Exposed port**: 8080
## Key Design Decisions
- Docker CLI is installed inside the container because the unlock workflow needs `docker load` and `docker image inspect`
- Cython compilation happens at build time — the `.so` files are generated during `docker build`
- `pciutils` is installed for `lspci` (GPU detection in `hardware_service`)
## Required Volume Mounts
| Mount | Purpose |
|--------------------------------------|----------------------------------------|
| `/var/run/docker.sock` (host socket) | Docker-in-Docker for image loading |
| `/opt/azaion/images.enc` | Encrypted Docker image archive |
## Image Tags
Tags follow the pattern from Woodpecker CI:
- `main` branch → `loader:arm`
- Other branches → `loader:{branch}-arm`
- Registry: `localhost:5000`
@@ -0,0 +1,42 @@
# Observability
## Logging
**Library**: Loguru 0.7.3
**Sinks**:
| Sink | Level | Filter | Destination |
|--------|---------|-------------------------------------|--------------------------------------|
| File | INFO+ | All | `Logs/log_loader_{YYYYMMDD}.txt` |
| Stdout | DEBUG | INFO, DEBUG, SUCCESS only | Container stdout |
| Stderr | WARNING+| All | Container stderr |
**Format**: `[HH:mm:ss LEVEL] message`
**Rotation**: Daily (1 day), 30-day retention (file sink only)
**Async**: File sink uses `enqueue=True` for non-blocking writes
## Health Checks
| Endpoint | Method | Response | Purpose |
|-------------|--------|--------------------|------------------|
| `/health` | GET | `{"status": "healthy"}` | Liveness probe |
| `/status` | GET | `{status, authenticated, modelCacheDir}` | Readiness/info |
## Metrics
No metrics collection (Prometheus, StatsD, etc.) is implemented.
## Tracing
No distributed tracing is implemented.
## Gaps
- No structured logging (JSON format) — plain text only
- No request-level logging middleware (request ID, duration, status code)
- No metrics endpoint
- No distributed tracing
- Log directory `Logs/` is hardcoded — not configurable via environment